// ==UserScript==
// @name           KOC Power Bot
// @version        20130304a
// @namespace      mat
// @delay          1000
// @homepage       http://userscripts.org/scripts/show/101052
// @include        *.kingdomsofcamelot.com/*main_src.php*
// @include        *.kingdomsofcamelot.com/*platforms/kabam*
// @include        *apps.facebook.com/kingdomsofcamelot/*
// @include        *kabam.com/kingdoms-of-camelot/play*
// @include        *facebook.com/connect/uiserver.php*
// @include        *facebook.com/*/serverfbml*
// @include        *facebook.com/dialog/feed*
// @include        *facebook.com/dialog/stream.publish*
// @include        *facebook.com/dialog/apprequests*
// @require        https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
// @require        https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/jquery-ui.min.js
// @description    Automated features for Kingdoms of Camelot
//
// @grant       GM_getValue
// @grant       unsafeWindow
// @grant       GM_deleteValue
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_listValues
// @grant       GM_addStyle
// @grant       GM_xmlhttpRequest
// @grant       GM_log
// @grant       GM_registerMenuCommand
//
// ==/UserScript==

var Version = '20130304a';

// These switches are for testing, all should be set to false for released version:
var DEBUG_TRACE = false;
var DEBUG_SEARCH = false;
var ENABLE_TEST_TAB = false;
var ENABLE_ATTACK_TAB = false;
var ENABLE_SAMPLE_TAB = false;
var DISABLE_BULKADD_LIST = false;
var ENABLE_GM_AJAX_TRACE = false;
var SEND_ALERT_AS_WHISPER = false;
// end test switches

var MAP_DELAY = 4000;

var DEFAULT_ALERT_SOUND_URL = 'http://koc-power-bot.googlecode.com/svn/trunk/RedAlert.mp3';
var SWF_PLAYER_URL = 'http://koc-power-bot.googlecode.com/svn/trunk/alarmplayer.swf';

var URL_CASTLE_BUT = "";
var URL_CASTLE_BUT_SEL = "";
var CHAT_BG_IMAGE = "%2F%2F5v%2F%2F1v%2F33v%2F31vf35v%2F3zvf33v%2F3xff31vf3zv%2Fv3u%2F33v%2Fv1v%2Fvzvfv1vfvzvfvxffvvffmzu%2Fmvebmvffere%2Feve%2Fete%2Fere%2Fepebevebeteberd7evd7ete%2FWpebWtd7Wtd7Wrd7WpdbWrd7Ord7OpdbOrdbOpdbFpc7FtdbFnM7FnMXFrc7FlM69rc69nM69lM69jMW9nMW9lMW9jL29nL29lM61jMW1nMW1lMW1jL21nMW1hL21lL21jMWtlLW1lL2tnL2tlL2thL2te7WthL2le72lc7WlhL2la7Wle7Wlc7Wla62le62lc7Wce7Wcc62chLWca6WcjK2cc6WchK2ca62cY6Wcc6Wca6WUhK2Ua6WUa6WUY5yUY5yMa5yMY5yMWpSMa5SMY5SMWoyMY5SEa5SEY4SEe4yEY4yEWoyEUpx7Uox7Wox7UoR7WoR7UoRzUntzY4RzSntzUntzSnNzSntrSmtrY3NrSmtjOhlrzmNaSjpjhBljxRljvRljtRlarRlapRlSnBlSlBlKjBlKhBlKexlCexlCcxlCa0o6CCE6Uhk6Yxk6WkopAEIpADopABAxQjEpEDEpCCEpMRkpMTohADEhACkhCDEZACkZACEZCCEZACEQABkQABkIABAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAagHQAgAI%2FgB1NGgAB02XJUaWKFziZEmShRAVOplIcSIUKA4fLsG4EUqVj1kqNpQosmJEJ1VGSvx4saXLlwxLTvxYReFHmSgnkqRJkabPn0CrvGypE2fFlEZLCl3I8SJEKCirZJmKNGlJIxRJjoza0CREq0eVBq0KNqdIpFo7ehQ61OVYLTSnZoGbUUoSJ0yeNJlR4EGdOGsCC37jRvAaN4gDI37DuDHjOI3dOHYcR46cyZgzI94cmfMby6BBZ34Tp7Tp0ocZFx79GPNp03LsjLZcGjRk1ZJZE278%2Bvbj3qZVH0482rQdO8DjbEZ8OnHwNaU9q9ZNOvnpzryTvzEcuLRr4MWt%2Fgev%2FpoOHdPm0zOWszkOm%2Fc3HjxY42QGChQmRNw%2FQaL%2FiRP7%2FYeCCAT%2BR6B%2B9yUYoIAKmuCgCSVEWMKDD5aAH4UOXkghCvz15yEJCoYoIgoT3gehCSRieKKEEkIogoQj3pcChx7%2Bx99%2FH%2F7H4o4RoohCCjNyaOOCAIb4YX8xJriCggDqGGGRIloo4oYaVgjjiBnGmGWSCdqIoopbhljhg1yWaeYKQJZwwoEjjHBDAgmoYcQGfRVg550DFJCnnQP0ead88tkJ56AJCEoonAUMpOiddiraAKOQRsrooZQOmqiji17qqKaLYurpp54WUGilk3IKaqiMNuAnpIiuKiqi%2F68W2uhAktYKKa13nqorpolemmukj9p6a6278kqqsH8%2B8CcEyhZwwAGMPgCBnQI1sIYRIDQAQbGbcmqqow%2BAGm64npKL6bjncituA%2BiiO1C77MYL77i5BtuXueqCqum37ALq77%2F%2B5vvuv%2F0GPLDBBhfbLr6KAkxwwacCKnC6706M67f1OhtBBBAcwOwADjgwA7tygJGEDjrkoPLKKvuwsg8w5wCzD0MMMXMOKKO8MhApsywzD0AHLfTQQc88NMxBDwHE0kwD4fPLM0dtdNRAU0200DPXXDPNWnettNc8s8yz1DPPYHYOVZNt9NE%2B6KB0z27rvDLKRa9dddBo86C21f5D5%2B3D1XjnMMPKgO8NeN12H6643joA0TXPTXstueQ%2FDPFDD5gXofkPlQuRgwQSwOGGGmecAcbpqIOxhRVWSCEF663DLrsVW9Re%2B%2By45667FVTsrvvrwPsu%2FPC2F7867Lfvfjztt9vOfPLD0%2F588dFXb73yy%2Bee%2FfXcd8%2B98eCHD%2F4ZcMxRRx1zwHHGEkQwQQcj8O%2FRRx8vMOBAHX2Iov%2F%2B%2FPfv%2F%2F8ADKAAB0jAAhrwgAhMoAIXyMAGOvCBEIygAxmhhyUUgQ3wy%2BALDKCAOeRPgiAMoQhHSMISmvCEKEzh%2Fxixhh6IIYOMaIEBDOBBFdrwhjjMoQ53yEMJsrAK7%2F6DXwsIQIAa9vCISEyiEpfIRAMyogtV2AP8XkBEIzbxiljMoha3%2BMA9ZGENU1RABz%2FIxTKa8YxoZCIZjBDGMYLijXCMoxznSMc62vGOeMyjHvfIxz768Y%2BADKQgB0nIQhrykG%2FcQxQZ8QIxehCRkIykJCdJyUpa8pKYzCQoGMGFNjByho%2FUpChHScpSmvKUqBRkF7gQQ0f2IZWwjKUsZ0nLWuIxCzuIIQdDacte%2BvKXwAwmIHGpSzcK85jITKYyY0nMFrhymdCMpjSnWchmPpOa2MymNrNpTWNu85vgDGcvs9CDVnpTnOhMpzozmQUimNODnYinPOdJz3ra8574zP%2BnPvfJz376858ADahAB0rQghr0oAhNqDzJ%2Bc4%2BKPShEI2oRCdK0Ypa9KIYjWc34ZnRjnr0oyANqUhHStCNOpSkKE2pSlfK0pbmk6HOHKNLZ0rTmtr0piUtZyNlitOe%2BvSnQE0pQ3fK0aAa9ahITWpBh%2BpKpTr1qVCFKlN5GtWqWvWqM4UpKE%2BK1a569asZbacuachVsJr1rGgtqTtlSFZNuPWtcI2rXOdK17ra9a54zate98rXvvr1r4ANrGAHS9jCGvatYmWrBw%2FL2MY69rGQjaxkJ0vZyro1C0Uo5mIty9nOevazoA2taAOLWc32YbSoTa1qV8va1t61CkdoqGv%2BZ0vb2tr2toGFrWxxy9ve%2Bva3qdUtUU8L3OIa97jIHaxwXZnc5jr3uc9d7hihS93qWre20t3sdbfL3e5aVrcx9SAlxkve8pr3vOhNr3rXy972uve98I2vfOdL3%2Fra9774za9%2B90veKhQBEuHVA38HTOACG%2FjACE6wghfM4PFC4QgAdqSAG0zhClv4whjOsIbt%2B%2BAIj3HDIA6xiEdM4hKztwpIgIQKXNmISbj4xTCOsYxnTOMa2%2FjGOM6xjnfM4x77%2BMdADrKQh0zkIhf5EpagxBVSTNQ88OHJUI6ylKdM5Spb%2BcpYzrKWt8zlLnv5y2AOs5jHTOYym%2FnMUH5Cilv%2BsIAF5CEPf4iznOdM5zrb%2Bc54zrOe98znPvv5z4AOtKAHTehCG%2FrQiE60nO0CCRsgwM1%2BAISkJ03pSlv60pjOtKY3zelOe%2FrToA61qEdN6lKb%2BtSoTrWqJ22FJEBiBgPoYKRXTeta2%2FrWuM61rnfN614DwgpLgAQMBCDrQBj72MhOtrKXzexmO%2FvZ0I62tKdN7Wpb%2B9rYzra2t83tbnv72A2BxE7T4AdBmPvc6E63utfN7na7%2B93wjre8503vetv73vjOt773ze9%2B%2B%2FvcRoiCh8n974Ib%2FOAIT7jCF87whjvc3EaA8LjzMIiKW%2FziGM%2B4xjfO8Y57%2FOMgD7nIR07%2F8pKb%2FOQoT7nKV87ylls8CRIXYxryQIia2%2FzmOM%2B5znfO8577%2FOdAD7rQh070ohv96EhPutKXzvSm2zzi4pY5zZ1O9apb%2FepYz7rWt871rhPCCEyWeiHGTvaym%2F3saE%2B72tfO9ra7%2Fe1wj7vc5073utv97njPu973TnawR10BMzeE4AdP%2BMIb%2FvCIT7ziF8%2F4xjv%2B8ZCPvOQnT%2FnKW%2F7ymM%2B85gcP9Q12MA%2BbD73oR0%2F60pv%2B9KhPveoFnxAAgzIPh4i97GdP%2B9rb%2Fva4z73ud8%2F73vv%2B98APvvCHT%2FziG%2F%2F4yE%2B%2B7I3ABNfTMA%2BIiL70p0%2F96lv%2F%2BtjPvva3z%2F3u%2Fnv%2F%2B%2BAPv%2FjHT%2F7ym%2F%2F86E%2B%2F9Jn%2F9znkIRHwj7%2F850%2F%2F%2Btv%2F%2FvjPv%2F73z%2F%2F%2B%2B%2F%2F%2FABiAAjiABFiABniACBh%2FftdICOB%2BivCAEBiBEjiBFFiBFniBGJiBGriBHNiBHviBIBiCIjiCJFiCJniCEAhzABYy7rcILviCMBiDMjiDNFiDNniDOJiDOriDPNiDPviDQBiEQjiERFiERviCKtgCDtCAeXCETviEUBiFUjiFVFiFVniFLpgEUKBibeZ%2BjvCFYBiGYjiGZFiGZniGaJiGariGbNiGbviGcBiHcjiHdFiHdniHYPgDUBAJKvB6j%2FCHgBiIgjiIhFiIhniIiJiI%2F4q4iIzYiI74iJAYiZI4iZRYiZZ4iYAoBcHGAyEDB1SgAgAQiqI4iqRYiqZ4iqiYiqq4iqzYiq74irAYi7I4i7RYi7Z4i7iIix1gA1kQASk2AwLQAHjQBSeQi8Z4jMiYjMq4jMzYjM74jKi4i13wASmWAwMgjGggAtC4jdzYjd74jeAYjrlIAjfgBRmgBJDgA9qCB2WgjeL4jvAYj%2FI4j%2FTIiiJQA1iQAVMACT8gLXZABu5YjwI5kARZkAZJixsQA1dQAQLnAwnwAHZQBiNwkBRZkRZ5kfOYkAspcDdQABAQkROJkSI5kiRZkre4ATRwBR8gcDXgkSBpkjAZkzI5k%2F%2F3yAUfsI80wAASgAfZOJM%2B%2BZNAWZAj0ANecJOvNgA72ZNBuZRM2ZTcOJRFuY868AAMwJMo4JRYmZVaeYscIAMqmWJTWZVkcJVbWZZmeZameAEKuZKQMJXCOJZoGZdyqZVqqZINuS14AJdzuZd86ZMXgAM2KXA7gJdlQJZ9eZiIiZEbsAM2mWKD%2BZaGmZiSOZkCuZhXgAGOuS3%2FGJmU2ZmeCY4b4JUVkJkNsJmfeZqouY0XIJoC9wN98Y8BmZqyOZu5CAIxEJjp%2BJpKSZu82ZuxaJt2mZsPgAdrEJu%2BeZzIaYq2iZs%2B0BfEaZzJGZ3IqZFs2ZzDWZzSmZ3JqZEY0JD%2Fzomd2hmevAmc3RkJ1mkHagCd4rmenUmeU2Ce8mEHu8me9EmZ7mme7FIHYxAC9dmfk8kBMeAF5amOfrGf%2Fnmgh9mVRRkF%2BFmg%2FImgECqXobmgkfAD%2BUkGDxqhGlqWCrqSFXqhGbqhIuqUAEqhBKqfITqiKgqUtimgDHqiBrqiMvqTLZoBL5qfMTqjOgqTCUmhNCAfepCjOzqkIjmhHvqjDxCkKUqkTHqQG1ADPgqkQtqkVEqQTxqlSTqlVbqlGQmlRxoueKClXDqm4nil1BgJPyqMYkqmbNqNZsoEaAqma9qmdOqMZsqgaaqkdbqn3Gik7%2BkD8lEHGMqnhGqnNaCS%2F3AKqH7RjoXaqMr4pJeZqIHKqI5aqbm4mpEKn4uqnpbaqa%2BIqQM6qZzqqaSqiqD6oqJaqqrqihdwqB6qqHVAqas6q6jYqpkKq7JKq7o6ipCKmXGapAC5q8IqipD6AXCKpHoQrMMqrMV6rECqrMuqq72KBL%2Bal6MarZ36pFXgq0iKB19wrdhaqdNard8arrRqmRjgrMJYrua6qugKpyOzruDaroTKATuAqJFQLYLqAfSqqnV5k%2Fk6ELHKr%2F1KqnWZrgHbAPtasAarkAirr2RAsAxrqdwJpxArsRPrqKGZqRebsZYKqhYrsBHrsZW6mlpgrAm7sCTbqKtZlCFbmuy6sv%2BEOgEKmQEvawcxK7N7SrOXSa3Vogc5q7N0agEOC5bycQfQKrRDW7Rt%2BazzqrRMSrQ927TASgJQW6dS66tTWbVXS6c8251Um6xP27U6%2BrUNKaVWS7ZkSp4phqxzqrZDSp4Cl6ZhuqRwy6Ry%2B6t6erdbmrdua7d8u6PciafSsreB26SDG6cQYLiHS6TcSa0zIKWA27gr%2Brjm6ZxqMLmUO6IJ2ZiXO5yZu7mOe5u%2Bap14ELqiK7gxoAUIa7qom7ozapusm6jscrqaC7sQ2qKtW7uvi7sq2qMoS6C267syCry0C7q3S7z9abyaKqjJq7z0Camj2ZYgCr2ce6ijGbB%2BMaj%2F1ruh4yoQftG73Yug38su6Pm846ud5QuR4pu%2B%2FWmrZwq%2BddC%2B7kuftqq11Vu%2FB2oBh4qZ1Mu%2B6Ku%2F0xkDWOC%2F4Hu%2BAuyfPWrA5ku%2FCay%2BAUqN%2F4vADxy9AcrAAFzBFlzAYLmODqzB26mQ0ysQEDC8ICyeGjnC67gGAXzCqZmQHBy23OvC2QnD3PqsLUzDn2nDbRsujKvDAxzDefq2QCybC9zDDfDDRdybwEutQ5zDSyyZTay3MxzFTHzBPQysUGzFh5nCEAarVczFsjkB9zi1YLzFYjyXE8AB%2FUutZ5zGvLmxpRuoYQzHp3mwbkzHaGzHaInHzVvHfNyZfvzGgYya%2F3Kcx9u7x4W8lZYbuUmKBsW4yJ%2FJtvkqpSUgyZNctNVKxJg8l8CZAZAruZ3cnjUbylmqyKPMlJ%2FsxOFiB5ycyme5ynFammCAyrDMogQMyrPsyrZ8yz5pm%2FnIysJYy76MmBqZAU0QCY6sxMUcl5%2BczMsMyM0cy7mczG47ttPclC36AdYspdiczUsJAl4KzU4Lzp4cwaycpd9szjQawd08zL3MziIpuyi7tc4rz2gpzldgs9p7z%2Fhslvp8pCIbz%2F9ckeIcmGiavwWtlQHtxAq90FhJyfJrBgQN0QWZuDSQnxRt0VkJAl5ZnjTQF3Ww0RztlPpcno7MyyVt0hHMoCn9yv8rTZK669LxCdMxPc%2BkS9MQadM3fZHLidI1XdE9HY%2FbbMrMPNQmOcXLzNNI7aTorMyi3NQzCcM2qrdMLdVWGsHOOpxXjdUCuc3kPJzE7NUwCdZQLdZCTdbdaNaRC89qbZJmTbdj%2FdYjuc3vKddpTdfPaNezXLd6XdcBqo%2Bfi6J%2FjdPm%2BKci3dWFHY4g4AKHPdiKvdjfuAErkI%2BI7aCSbZGUbdmf%2B495ndnISNn7fNevKc2gTY%2BiLdjN%2BZGmfdrymNqJWtqf7dq4uAEscKv%2B%2BMG0DY8aoMnn2dq7LY4akJKlm9izHdy0ONw9C9nHjdyyqAH9G9uJ7Nz1CN24Pd3UPY%2F%2Fyl3cmJ3d8tjby92cDSAHY6AB3i2PX%2BvGieLX5w2PNLut6p3Ekd3eufjecyzfzU3fqmjfeYzf%2Bi2O%2FA2f%2Fv3f4Njb8C3gR03gzjjc2xrbA67g3bjdDs7eEM6Nyo2yIY3dFb6Ntm2OxyrSwL3hx6gBLCCg8GrcIr6NJG7iaAri%2BZ3iALDiCJvh%2FgzjzagBMODhv1rjNr6MOK7jNB7iPV6LP87PND7fQ66KRe7EiY2xST7iKWnkKP7kyajcUr7TL57iF%2F7hrJ3lIq4BOoCvId3lVF7lYQ6wGa7SZQ7lKkna3b3muWjl76kDTQ7nxsjgGDDnIrvOdo6KFZuwsNnntU0D%2F6yLqhCZq4I%2Bi4m7tYGe6LXYqwyaA%2BYr5I7u5%2FeKsCMDkSNb6Yp%2B6ccqsk7O6ax6qPwMsXwu6gBgAV7pofK76aj%2BqQ4rcK0e6q9uqrFOvQrr6rXOinLMoLO%2B6664sVWNpCoL7KuolgiNpDh76qJOtDa51XcQtMZ%2BijyL4a0s7dNeiuldyVqc7aqYtT7LLneA5IkO7pEg6afs7alo7pK%2BuJQO7H%2Fe7smatupuitQZsu5O7%2FVOiouuLfO%2B7%2FYe69r77wDP7wIv6Q0w7vpe8ACQtyRM8Awfig5fuO%2B%2B6xPv7l6%2B4f2O8RFPrJpMwp7d8aFouSCv296et6ttByws8g2%2Flv%2Fqjbwsn7ium%2FEVLvOYS%2FMQ3rkDevMxf5uvqps4r%2BBG%2BqKyHfMyIKAvz%2BMMH5oczNws35ULmWKE3PHTmo7%2BiAZBT%2BBPGsxWX8Imn%2B1bD8q5%2BZFYH%2FP4qMvnWfYiP67WqfQFb7m%2FnfX%2F%2FbhdL59yr98JybpSLx88eff0fcRW%2F8h%2B396Ar6h6oPZUj8WBf%2FiDf94pvPeC3%2FNRv%2FiIH%2FE6n8WM3%2FNcANJ9kflrT7pSbycJru6Xn5sFMPreXviJgvpg%2F9TWmayN792de6YZ7vkdj8eQMOZ9L%2FkYAGFjHvIdv8arHvrbuwEiL%2FxmHNRP75W6TOzkLugc4AL7jMhqTvXSP8f%2BWB7z18%2Fk2f%2F5y92tz9%2FncF%2B4lb%2F0mvyji4sGl%2Bz92M%2F60265f8v7Rh3%2Bdg7%2Fchr72Q2ctN%2FKcx3x%2Bg8QTCL5eNDADpgQABQuZNjQ4UOIESVOpFjR4kWMGTVu5NjR40eQIUNuiHEFg0AaDx7gGZNQ5EuYMWXOpFnT5k2cEEmaRBJphko9LXMOJVrU6FGkSUXuPOnzAQQ9alwqpVrV6lWsWSmCiKHlg0CCD4JO1VrW7Fm0aTly9fI1UsqVZMiqpVvX7l2qIGi0FTijgFi5eAUPJlw4pN62Pf0CnmvY8WPIhdl%2B6AnXjtDImTVvPssVS4YpA1VebszZ9GnUNtmCFv3%2BgHRq2LFlg0ScAWXBOphn7%2Bbd2yGIHV5sv8Wt2%2Fdx5KmBf65cvHRy6NEly2BOvEHu59K1b08LgjqG5g%2BwcydfHq33z02Iizdu3v17pOhZ%2F2SfHf59%2FDHlh6Y%2FPv9%2FAGGSTz368EAoQAQTXCuGz%2FhTyUD7FJRwQgBWc3Cl9ijUcMLJLmQpwg1DvK9Dp8TKUEQU8SNJuAvHSvHF%2F0j6TIn1giIBRhzhm4xGuGzM8cfydizRRSCLlM7CEj80csnkJiPwwROZlFK5GNpSz7Iop9RyMxLDem1LME9DMiz%2FwjQzszH%2FKvNMNg1Ls74245SsStbIzFJOPM0CYYUGW1szT0D%2Fz9qAzzoTgDNQRM3SYIUrWLvB0D8TlZSqRRsNzQdI75x005yYAms0TTkVlSamesIUAjvQAHFUVl%2FSoCTwInkU1cBatdWmV0361LVQb%2FV1Iw1oaDS8L381NqRgG72N11WPdVaiYLUYzsten7XWoWinBbXZa7sFIFtTcTvQW3KhFTaDygq4btxy222IAliXLdZdeieId7156W3XXl1by1ffcoVtilpuAb412YG3NdjdZIfDsuCFWW2YCUkIjrjcbCl%2B%2BGJyX5UWJXUj5fhYj9H1KeQxQBi5Ww1g%2BPgtNatdmdOWX4ZL5JkPdtlhlXDOuVWPP7gyZoh%2FDjRat2gg2miS%2FmnwCuRDmfZ1YpijltpWhJeto9arbd2ghn5TorXortvcYIewn7KD67JH%2FdqkKNbbmuy2zXwbg7hvlrlus2moAu%2BKC5Jjb77PJOnvuAm6ju3CJT0cbz%2FVEKFxTrmCeyAIXCNjcson1QvuwHnlvPNEP4c8pesIJ31K0%2FN2bvXSBXadWdgRvXv2f2s3G%2BzTQd1Ad0DP7jcsPBgHnk3hYw1Lj82Px3MDGrhQ%2FsHmnY8z1%2Bmttt5M7MOrowsPtm%2Bz%2B6q%2FD1%2F8M8lXWnv0tWyZp6qLH739Ld9vav2o5qd%2FSg1Y0LViNanhfPtzHwu0cL%2B%2F4EEqBKyfAREoljXQjYET6t8B%2FqGWvwnyz4HLwmAGmUQSCxKHAfLz4AerdL8HjHAM%2BithjjyGQhWysIUw6t%2F%2FlNaAoMhwhimqIQZCc0Mi7dCFLmuKXxqgJCEOUTi3OaLqkvifV7Xlh0Bx4hPxE8UPTNFEErTie7CoRQh18UVR9OF6wihGFLXMC2WkQQNoh0YRRZE1bXwjHDf0RXxV0Y7kwaMOFLZHDckxNH7EEBcBKZ0X%2FtCNxTPkIaFjvx%2F%2BRQ%2BqciQFiRhJsVCykgoq2RQksT47LHCTCULS%2BuogylEGqJRqMl4qR9SVpPWsla58DwhjyT5aerEkPHsAHPSYS97k6pa%2BbCQwY2OBXS6LmMbEDzLT%2FsYAXw6Qme5xZqxSAs0x%2FG6a76lmeJa5TWrCypu%2FBCdq1KeSb5aTj%2BJcDxzYpc7tvLA5DXBnMeGJpr1YswENcEMXtHlP7dSmJzpwYz0Bup3JoKQBEIgDOQ8amRVl0ScLbeiNHhqdFc3HjRW9KEbpNEh1NdSeHSUMkgjaSzBIk6S9QVIOGPCAhqp0pbvJaGhcisuZxqamJfJZTlGzAf8NZwb77KlPTQNUZUkiB0R1qFHvUsGvKJWpI3WqWqCq0NRRtapoqZlbTlqHd27VnC6L6lfBJ9bYXFUSOghZFjSAVtj0MFwFgIMRKADX1MhTVgkogBuMgNe8wpJifinAGn4A%2F1hzClYShDUsYk8TNI09oABqOKxjOWO%2FKGBCaZOtrGU1g1lMDJWznt0MZhfbgNGSNjP2G%2BwABkBZ1a42Bn9DwmJdC9vYQuZVfzvCWhvAANzm1jHY6y1BgNtZ4RaGuIFrQHCTW1JYFbcgavDBc90UXeZS17pzOqB0m1vd7Q4mBF0BzyehpNXw3oRqFkvvU88VLoM0tb05oRpckDhfujQsPPfFb1r06y%2F59rcmyaKMaNaFXgHDJFcmA2WAEyyTc9bxwWaJAROyl7sJW4VfCZNwhrGy4XB12MNWIR97R4wV7MnLwSf%2BCPa0iGEWH8XFeURwjDWy4L4szcZVqZnJZjAA9v6obMeU2hnUijpk9cJAWXJbMZIxAlm5zdLJOIGyKaU8ZVw5LWk6xnJR%2FmvKJnd5IvVFWY3FDJGsle%2FKZ46JBnSwZKWNjc1DcTOc1bbmOYvkcxm4Us%2FCnOeG7NmTYDYzoBXiYgA2YHCFNrTlMKAeH6hLDng2tEcc3WfxVK%2FSM5mxlzS9af0IzJMmBrWARG2dI5f6xueKZFZVrZ8385nGr1Ywq2dNa5EgbIrxZTSg68xhRuJazzTAQvaCLWzaCCxctNIhsp98Lzv1Os8pto4cwursG%2B9SMWXGtkcWvG0Rd%2Fsi9lMM9aQ9Z9ZGggdADuW52VzBk0hi3eJBpbgzAm%2BK6f%2BA3fW297g3ONGV8LvfFcH3kCQ38Hv%2Fmz5RKQHCn71GJvLX4WOmU2QLAOOJN0QDLrCgeZvo7jMXHHUSzzia%2F31DkpccW0TMMQ7%2FvOmaFVFdQVQ5mqt0S5rXHFs312LOdc4QPNIgc3q49s8PfcIpourllQ76QjFec0G%2BxelLN3TQ1UZ1X%2FM8En5UOsjF3MenpNzondy6G5nn9S73WJGMMfpDYo5JBaIdy1w54KD%2F0u62%2F6Yrc7y7wNtOd4laWe5TrjIrB%2B9kYS5r0XnXeEluKVLGAz2Z64F85I%2B%2B5KHScwxvtfy32DnUXo5Bpm0nH%2Bhj2nnPw48%2Blbd8hFkf%2BQhHE%2FX%2Bem0jPVM6e%2FJWZp%2FuHL3REaPPB%2FTz8EgOwV4cVtAuDH%2FIiEkaRVeI%2Boj2xfkWtfxOTT8G6kd%2BRWzcaNF9%2F9Gyw9T7P1%2BNQmGK9TwjqT%2Fon7Mty%2B3qzu%2FENh5PdcaROn9C1n%2FiSC3wV9nPZv7TPfEYP52zpXxzI7BSvh3bACUrKwQkQKjzn%2F5DwCzovZ8jt7KjpyS4q87DQIIqLOSCvQYcLNRqLNy7gqiCgX0ywQ4cwdNKrRZEwSnAhA90LtiDlRkULRtkvBSzrdcaAtRLPcoIrdsCwhMsrx8DLiPsQHGyLSUMwuXKAQf4riB0tN7igekCr86zwuzSQsvjQsXRLtT%2FA0OVEMMtzD0DM8MvJKKB2ic1FEGesC1%2BCkEeVDIkBDI4oMO8AwE7rK0f6yU9%2FLsm%2FMM8DMLxOqDaWh83CMTvsyE3ekPG24kPyCw6gsS8sxfE0ay%2FsMS2u4DZwoAl%2BKRH9MLIE4EeaItQrERSZDxTbIvMqsEgCMLbwQQfQC01iEXU44DgmERatEVG%2FLkNkAG40SzJKkTUu4AaWKMoMK8BMMb4%2B7yCcMbqc7wlcAp6wsVnRMFQpA84wMbqkwGvWMafuEZZrIEDyqyfaEZv1D5zvAB0fAB1lEVYoUR43MG8E4EY4AJeTInX%2BkWdczTXGQC%2FksfLQZ2BHMN8xBtiFMi%2F%2F0JIfQxINWjIM3zIhbTHtsNHiuRHizQ6jNxHN%2FTHmsNIDDgCqXuAjfw5DkjIuCGkk9S5lJSeVyxDkFS5l1RIlpzJkqvJmDTJdWQ8naTBMuzJvHtJXjwpTuTIZNzHv3CDJfzCpJxBRWzKyAOBp%2FykpZRKxvMOKbLK4MNJ%2B%2BM5rlxEedxKRfTK%2FeM5TezKscyitBRL6EPLG3LLM4Q4WlQJufxCGeCLulRL1BOBpGQCWlxKs3Q4fEwMTZzDKrw5wIxLrNzDE1pMdWHKxFwjJDhMyXxL4UjEqwxCXRSDD1iCwETMXNwBzwTNSJtDzrM8ESDNzwzNuyxF1jyCwOTLzltNz%2F%2FsrbIMQlO8zbYcTIQzgR64TasUzc4zgSJggw%2FAzcj0zYEzzjf4ACJgrtdkvBVggufsgdCZzrxjFDr4ABwYTu00ugngTu%2B0yr5iTnsbzyugAxP4zs0Kz58bTyxgz%2B9UHPjUOXvxAjxoz7okzsizlzDYA%2F6sRRA8xhUQAwHFgUw4qfusOQuQgTIQ0BhY0BVET3GzANLczxjoTxb8T9IUUBnoxeay0G6zFwRtTwqFwcjzxBPFARr0ReiTgRMlgkwgrKP8x%2BBkzyjYBBV8ADQgUWy7ACJgAzEwATTgBKF7AMNKzT1EgSVggyX4ADz4BKGjwi80gTBYgxUoAUag0gIoADT%2F8AEmFU8Q0IEw%2BIEUAANK%2BIQfgAAIIIMf4EDfmAA6nYCFkFOlsFOQwFOLqFM0G1OGoAAK8NNA1QA%2BfQhBTVRFTdQJGFRH1QANaFRJHdQ6pVMLoABIrdRK1QALsFM6hVRQBdVP5VRStQBOtQBUTVUL2IANUFVVnYBVvQBX7dRU%2FR0LAIENAAEQmAANKNMu0IESAIMuDYU4WwMjQIEQCIENSNZk1VVdDQERiFYRSFZpZdZoBQForVYR8ABu9QBWZVVmZVUPCIFxZVZzzVVsNVdqldZrRddv3QB2lVYTmFcUMAER4AARGIFoJddu7dZ1jdYSiFd2RQGCZdcSKIETSNgT%2FwhYaT1YEyBYFDhYhEXYhD3YhIVYjI3YEkCBFOhYjyXYj%2BXYFMDYjgVZjz3ZkBXZEzDZjIXYlDVZFkBZj2UBmk0BmqVZkGWBnG1ZnkWBFViBjP1ZoR3ZkSXYFWCBo%2F3ZjhVapm1ap3Xam41apG3am12BGNiBGtiBHTjaGXCCJAABH2CEURgFYj2AwjICGmCBGVBbGqCBGYABuIWBGJjbuW1bu73ZGUhbFoABqbVbv50BwM1btw1cwSXcuIUBv01cxU3cGsharM3aHugBIpjcHtDayn1cv%2FUBzfWBHfgBzyUCz%2FVcrd2BySUCIzAC0C3d0j1dI%2FjcH1DdJYhd1k0C1P9VXda9XdpFXSOIXd693SXI3dPlXd6lXeEt3iW4Xd8V3t29XSdoXuSd3SQwXuXd3eMN3ue93uuN3SLY3uKNXtml3iUogvAN3u%2BV3uIVX%2FE93iIwgvU13fXdXvgVXid4Ai3ogi8Igy5Ygh8Agx9omT4IhU8YBVEQugDwq%2BbNAgRO4CyogirIAi3QAgZ%2B4C54YC1QYASm4ApG4Al%2BYAvuYA%2F%2BYAZWYAzuAhIm4REmYS%2FQAi8IAzEQgzB4YS%2BI4RKeYfv9Ahv%2BAjLIYR0mgxfu4TAggzIoAx8eYiJ%2B4RwO4iDeYSLO4R5mYiPeYR5u4ij%2B4SLugiLGXxrO4hKuXy3eYAxTzuAvpuAJXmAHDmEEroLmfYInaF42doIqUOM1ZmM4nmMGZmMGvuM7hmM3ZmA1xmM%2F5uM5juM1ll8n4F04jmArLoM1YIMyWGMYGIAf6NKxFQVRCAgAOw%3D%3D";
var success_image = "";
var up_img ="";
var up_glow="";
var down_img = "";
var down_glow = "";
var gbtn_img = "";
var remove_img = "";
var remove_glow = "";

var JSON;if(!JSON){JSON={};}(function(){"use strict";function f(n){return n<10?'0'+n:n;}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}if(typeof rep==='function'){value=rep.call(holder,key,value);}switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}return str('',{'':value});};}if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}return reviver.call(holder,key,value);}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}throw new SyntaxError('JSON.parse');};}}());
var JSON2 = JSON;

//logit ("+++ STARTUP: "+ document.URL);
//Kabams new cheat detector
unsafeWindow.arthurCheck = function (a) {
  var b = false;
  for (var c = 0; c < a.length; c++) {
    if ($(unescape(a[c]))) {
      b = true;
      break
    }
  }
  if (b) {
    unsafeWindow.AjaxCall.gPostRequest("ajax/funnelTracking.php", {
      action: 1300,
      serverId: unsafeWindow.g_server,
      uid: unsafeWindow.moderators[Math.floor((Math.random()*unsafeWindow.moderators.length)+1)]
    })
  }
};
//uid 1729784 is our programmer friend Daniel from kabam

var upgradeData = 
{
  active : false,
  item : 0,
  retryInterval : 30,
  enhanceAction : false,
  enhanceItem : 0,
  enhanceMax  : 5,
  minStones : 100000,
  switchToUpgrade : true,
  salvageActive : false,
  throneSaveNum : 10,
  currentTab : null,
  trWinIsOpen : false,
  Opacity : 1.0,
  anyCity : true,
  uCityNum : 0,
  sCityNum : 0,
  repairAll : false,
  trWinPos : {},
  disableAnim : false,
};

var salvageData = 
{
  salvageActive : false,
  throneSaveNum : 10,
  minQuality    : 3,
  ruleSet       : [{"type":"any","faction":"any","conditions":[{"mustHave":"true","number":"2","effect":"Range","buffType":"e","slots":[true,true,true,true,true]}]},{"type":"any","faction":"any","conditions":[{"mustHave":"true","number":"2","effect":"Troop Training Speed","buffType":"e","slots":[true,true,true,true,true]}]},{"type":"banner","faction":"any","conditions":[{"mustHave":"true","number":"2","effect":"Siege Range","buffType":"e","slots":[true,true,true,true,true]}]}],
  numSalvagedItems : 0,
  maxStones     : 980000,
  anyCity       : true,
};

var upgradeStats = {
      upgradeSuccess: {
        0: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        1: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        2: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        3: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        4: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        5: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0}    
      },

      upgradeFailure: {
        0: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        1: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        2: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        3: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        4: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        5: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0}    
      },

      enhanceSuccess: {
        0: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        1: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        2: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        3: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        4: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        5: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0}    
      },

      enhanceFailure: {
        0: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        1: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        2: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        3: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        4: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0},
        5: {0: 0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0}    
      },
};

// Options in this area will not be saved between refreshes or reloads
var SessionOptions = 
{
  towerMonitorEnable : true,
  attackersRange : {},
  DisablePreset : false,
  protectItems: true,
}

var Options = 
{
  srcSortBy    : 'level',
  srcMinLevel  : 1,
  srcMaxLevel  : 7,
  wildType     : 1,
  unownedOnly  : true,
  mistedOnly   : true,
  hostileOnly  : false,  
  friendlyOnly : false,  
  alliedOnly   : false,  
  unalliedOnly : false,  
  neutralOnly  : false,  
  srcAll       : true,  
  srcScoutAmt  : 1,
  minmight     : 1,
  srcdisttype  : 'square',
  pbWinIsOpen  : false,
  pbWinDrag    : true,
  pbWinPos     : {},
  pbTrackOpen  : true,
  pbKillFairie : false,
  pbGoldHappy  : 95,
  pbGoldEnable : false,
  pbEveryEnable: false,
  pbEveryMins  : 30,
  pbChatOnRight: false,
  pbWideMap    : false,
  pbFoodAlert  : false,
  alertConfig  : {aChat:false, aPrefix:'** I\'m being attacked! **', scouting:false, wilds:false, defend:true, minTroops:10000, spamLimit:10, lastAttack:0, barbautoswitch:false, raidautoswitch: {}, },
  alertSound   : {enabled:false, soundUrl:DEFAULT_ALERT_SOUND_URL, repeat:true, playLength:20, repeatDelay:0.5, volume:100, alarmActive:false, expireTime:0},
  spamconfig   : {aspam:false, spamvert:'Join my Alliance!!', spammins:'30', atime:2 , spamstate:'a'},
  giftDomains  : {valid:false, list:{}},
  celltext     : {atext:false, provider:0, num1:"000", num2:"000", num3:"0000"},
  giftDelete   : 'e',
  currentTab   : null,
  hideOnGoto   : true,
  transportinterval : 60,
  minwagons    : 100,
  lasttransport: 0,
  reassigninterval: 60,
  lastreassign : 0,
  HelpRequest  : false,
  DeleteRequest: false,
  MapShowExtra : false,
  RaidRunning  : false,
  RaidReset    : 0,
  DeleteMsg    : false,
  DeleteMsgs0  : false,
  DeleteMsgs1  : false,
  DeleteMsgs2  : false,
  Foodstatus   : {1:0,2:0,3:0,4:0,5:0,6:0,7:0},
  Creststatus  : {1101:0,1102:0,1103:0,1104:0,1105:0,1106:0,1107:0,1108:0,1109:0,1110:0,1111:0,1112:0,1113:0,1114:0,1115:0},
  LastReport   : 0,
  LastCrestReport   : 0,
  MsgInterval  : 1,
  CrestMsgInterval  : 1,
  foodreport   : false,
  crestreport  : true,
  Crest1Count  : 0,             
  Crest2Count  : 0,                                     
  crestRunning   : false, 
  Crestinterval   : 5,    
  ThroneDeleteItems : false,
  ThroneDeleteLevel : 0,
  throneSaveNum : 10,
  throneDeletedNum : 0,
  RangeSaveModeSetting : 0,
  LifeSaveModeSetting : 1,
  RangedAttackSaveModeSetting : 1,
  TrainSaveModeSetting : 1,
  MarchSizeSaveModeSetting : 1,
  Opacity : 0.9,
  language : 'en',
  curMarchTab : "transport",
  ThroneCheckMatchingRows : true,
  ThroneSpaceWarning : true,
  ThroneSpaceCount : 3,
  CrestFreeSlots : 1,
  AllianceId : 816,
  PrevAllianceId : 0,
  throneMatchingRows : 4,
  captchaTimer : 0,
  captchaDuration : 10,
  captchaLastMarchCount : 0,
  captchaCount : 0,
  captchaLastCount : 0,
  consecutiveCaptchaCount : 0,
  FullEnable : false,
  DebugEnable : false,
  TestEnable : false,
  baseRequest : 8,
  randomiseRequest : 4,
  useNewSalvage : false,
  shortNonMarchDelay : true,
  logAutoCrest : true,
  logAutoTrain : true,
  logAutoTransport : true,
  throneAttackSlotEnable : false,
  throneAttackSlot : 1,
  thronePresetAttacking : 0,
  thronePresetArchers : 0,
  thronePresetHiding : 0,
  thronePresetScout : 0,
  thronePresetNonRange : 0,
  trainingThronePreset : 0,
  craftingThronePreset  : 0,
  liveRange : false,
  alertTR2:false, 
  thronePresetTraining:0, 
  thronePresetTrainingWaitTime:60,
  RecentIncomingActivity:false,
  throneNonRangeLimit : 10,
  desertionChatEnabled : true,
  shortMarchDelay: 1,
  lastMarchFailed: false,
  changeGuardianOnAttack: false,
  autoHideEnable : true,
  autoHideTime : 60,
  autoHideTroopCount : 1000,
  autoHideScoutKillers : false,
  autoHideHorseKillers : false,
  autoHideKillWagons : true,
  autoHideBloodthorn : true,
  autoDefendEnable : false,
  autoDefendMightLossLimitEnable : true,
  autoDefendMightLossLimit : 5000000,
  autoDefendMightLossLimitBase : 0,
  autoDefendMightLossLimitTrip : false,
  autoDefendHorseCount : 600000,
  autoDefendCities : {},
  autoDefendWagons : true,
  autoDefendHideHC : true,
  autoDefendHideSiegeWall : true,
  autoDefendSWHideCount : 10000,
  autoDefendHCHideCount : 90000,
  autoSacrificeEnable : false,
  autoSacrificeCount : 0,
  autoSacrificeMaxSacrifices : 10,
  autoSacrificeTroopCount : 6000,
  autoSacrificeTroopsRequired : 1000000,
  autoSacrificeHC : true,
  autoSacrificeLastSacrifice : 0,
  autoSacrificeResetTime : 12,
  autoSacrificeTroopType : 12,
  towerRangeWarning : true,
  stopCrestOnChanges : false,
  crestStartMight : 0,
  crestStartGlory : 0,
  crestLossThreshold : 1,
  craftingSaveAmount : 100000,
  rangeReinforcementThreshold : 10000,
  bootRangeReinforcementHiding : true,
  autoItemUpgradeSaveAmount : 100000,
  autoTrUpgradeLeaveTokens : 0,
  autoItemUpgradeMaxTokens : 0,
  autoTokenTries : {},
  salvageInterval : 20,
  autoHideWagonThreshold : 20000,
  autoHideRestoreState : {},
  preAttackDefendState : {},
  preAttackThroneState : undefined,
  attackersRange : {},
  throneReadInterval : 5,
  marchCount : 0,
  Version: "",
  marchFavourite : {
      0:{0:"200K mm",1:0,2:2e5,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0,15:0},
      1:{0:"200K archers",1:0,2:0,3:0,4:0,5:0,6:2e5,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0,15:0},
      2:{0:"200K cats",1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:2e5,13:0,14:0,15:0},
      3:{0:"200K wagons",1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:2e5,10:0,11:0,12:0,13:0,14:0,15:0},
      4:{0:"Protected Wagons",1:0,2:0,3:0,4:0,5:0,6:180000,7:0,8:0,9:20000,10:0,11:0,12:0,13:0,14:0,15:0},
      5:{0:"200k HC",1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:2e5,9:0,10:0,11:0,12:0,13:0,14:0,15:0},
      },
  marchAutoKnight : false,
  marchDestinationX : 0,
  marchDestinationY : 0,
  allianceList : {},
  hideDefendingThreshold : 200000,
  rangeUpdateEnable : false,
  rangeUpdateUrl : "Enter URL Here",
  updateRangeInterval : 10,
  thronePresetButtons : true,
  customSlots : {},
  itemUpdateUrl : "Enter URL Here",
  mklag : false,
  assumeAttackSacrifice : true,
  colorCityTabs: true,
  outputDebug : false,
};
//unsafeWindow.pt_Options=Options;

var attackData = {};
var sacrifice = {};

var playerThroneItems = {};
var playerThroneItemStats = {};

var TABLE_SCALE =1.0;

var GlobalOptions = 
{
  pbWatchdog   : false,
  pbWideScreen : true,
  pbWideScreenStyle : 'normal',
  autoPublishGamePopups : false,
  autoCancelGamePopups : false,
  autoPublishPrivacySetting : 80,
  pbupdate : true,
  pbupdatebeta : 0,
  pbNoMoreKabam : false,
  escapeurl : null,
};

var CrestOptions = 
{
  Running     :   false,
  CrestCity   :   0,
  RoundOne    :   false,
  RoundTwo    :   true,
  lastRoundTwo  :   0,
  X       : 0,
  Y       : 0,
  R1ST      : 0,
  R1MM      : 0,
  R1Scout   : 0,
  R1Pike    : 0,
  R1Sword   : 0,
  R1Arch    : 0,
  R1LC      : 0,
  R1HC      : 0,
  R1SW      : 0,
  R1Ball    : 0,
  R1Ram     : 0,
  R1Cat     : 0,
  R2ST      : 0,
  R2MM      : 0,
  R2Scout   : 0,
  R2Pike    : 0,
  R2Sword   : 0,
  R2Arch    : 0,
  R2LC      : 0,
  R2HC      : 0,
  R2SW      : 0,
  R2Ball    : 0,
  R2Ram     : 0,
  R2Cat     : 0,
};

var RequestData = {
  Queue: [],
};

var EnableOptions = true;

var CrestData = new Array();

function CrestFunc (Arr) 
{
  if (Arr == undefined)
    Arr = CrestOptions;

  this.Running    =   true;
  this.CrestCity    =   Arr.CrestCity;
  this.RoundOne     =   Arr.RoundOne;
  this.RoundTwo     =   true;
  this.lastRoundTwo   =   0;
  this.X        =   Arr.X;
  this.Y        =   Arr.Y;
  this.R1ST       =   Arr.R1ST;
  this.R1MM       =   Arr.R1MM;
  this.R1Scout    =   Arr.R1Scout;
  this.R1Pike     =   Arr.R1Pike;
  this.R1Sword    =   Arr.R1Sword;
  this.R1Arch     =   Arr.R1Arch;
  this.R1LC       =   Arr.R1LC;
  this.R1HC       =   Arr.R1HC;
  this.R1SW       =   Arr.R1SW;
  this.R1Ball     =   Arr.R1Ball;
  this.R1Ram      =   Arr.R1Ram;
  this.R1Cat      =   Arr.R1Cat;
  this.R2ST       =   Arr.R2ST;
  this.R2MM       =   Arr.R2MM;
  this.R2Scout    =   Arr.R2Scout;
  this.R2Pike     =   Arr.R2Pike;
  this.R2Sword    =   Arr.R2Sword;
  this.R2Arch     =   Arr.R2Arch;
  this.R2LC       =   Arr.R2LC;
  this.R2HC       =   Arr.R2HC;
  this.R2SW       =   Arr.R2SW;
  this.R2Ball     =   Arr.R2Ball;
  this.R2Ram      =   Arr.R2Ram;
  this.R2Cat      =   Arr.R2Cat;
};

var TrainOptions = {
  Running    : false,
  Troops     : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  Threshold  : {1:500,2:500,3:500,4:500,5:500,6:500,7:500,8:500},
  Max        : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  Gamble     : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  Workers    : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  Item       : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  Keep       : {
                1:{Food:0,Wood:0,Stone:0,Ore:0},
                2:{Food:0,Wood:0,Stone:0,Ore:0},
                3:{Food:0,Wood:0,Stone:0,Ore:0},
                4:{Food:0,Wood:0,Stone:0,Ore:0},
                5:{Food:0,Wood:0,Stone:0,Ore:0},
                6:{Food:0,Wood:0,Stone:0,Ore:0},
                7:{Food:0,Wood:0,Stone:0,Ore:0},
                8:{Food:0,Wood:0,Stone:0,Ore:0}
               },
  Enabled    : {1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
  SelectMax  : {1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
  Resource   : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
  UseIdlePop : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
  CraftingRunning : false,
  CraftIntervallMin : 3,
  CraftingActif : {3000:false,3001:false,3002:false,3003:false,3004:false,3005:false,3006:false,3007:false,3008:false,3009:false,3010:false,3011:false},
  CraftingNb : {3000:0,3001:0,3002:0,3003:0,3004:0,3005:0,3006:0,3007:0,3008:0,3009:0,3010:0,3011:0},
  CraftingStats : {},
  actr  : false,
  AsTroops     : {1:50,2:50,3:50,4:50,5:50,6:50,7:50,8:50},
  AsEnabled  : {1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
  AsSelectMax  : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
  AsMax        : {1:51,2:51,3:51,4:51,5:51,6:51,7:51,8:51},
};

var FarmOptions = {
  RallyClip: 0,
  Running: false,
  MinMight: 0,
  MaxMight: 999999999,
  Interval: 0,
  SendInterval: 10,
  MaxDistance: 20,
  Inactive:30,
  DeleteReports:false,
  Troops: {1: 0,2: 0,3: 0,4: 0,5: 0,6: 0,7: 0,8: 0,9: 0,10: 0,11: 0,12: 0},
  FarmNumber: {1: 0,2: 0,3: 0,4: 0,5: 0,6: 0,7: 0,8: 0},
  CityEnable: {1: true,2: true,3: true,4: true,5: true,6: true,7: true,8: true},
  CityLevel: {0: true,1: true,2: true,3: true,4: true,5: true,6: true,7: true,8: true,9: true,10: true,11: true,12: true},
  Diplomacy: {friendly: true,hostile: true,friendlyToThem: true,friendlyToYou: true,neutral:true,unallied:true},
  FarmMarches: [],
  farmMarches: {},
  Attacks:0,
  Checks:0,
};

var ThroneOptions = {
  Active:false,
  Interval:30,
  RepairTime:0,
  Tries:0,
  minStones : 100000,
  Good:0,
  Bad:0,
  Items: [],
  Salvage:{Attack:true,Defense:true,Life:true,Speed:true,Accuracy:true,Range:true,Load:true,MarchSize:true,MarchSpeed:true,CombatSkill:true,IntelligenceSkill:true,PoliticsSkill:true,ResourcefulnessSkill:true,TrainingSpeed:true,ConstructionSpeed:true,ResearchSpeed:true,CraftingSpeed:true,Upkeep:true,ResourceProduction:true,ResourceCap:true,Storehouse:true,Morale:true,ItemDrop:true},
  SalvageQuality:0,
  saveXitems:0,
  thronekeep:1,
  itemAttributes: {},
  ignoreWildBoosts: true,
  ignoreWallBoosts: true,
  protectList: [],
  enableMassSalvage: false,
  salvageToMainCity : false,
  salvageMainCity : 0,
  salvageToMainLowLimit : 20000,
};

var AttackOptions = {
  LastReport        : 0,
  MsgEnabled            : true,
  MsgInterval         : 30,
  Method          : "distance",
  SendInterval      : 8,
  MaxDistance           : 40,
  RallyClip       : 0,
  Running           : false,
  BarbsFailedKnight   : 0,
  BarbsFailedRP     : 0,
  BarbsFailedTraffic    : 0,
  BarbsFailedVaria    : 0,
  BarbsFailedBog        : 0,
  BarbsTried        : 0,
  DeleteMsg             : true,
  DeleteMsgs0     : false,
  Foodstatus      : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  MsgLevel          : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true,9:true,10:true},
  BarbsDone         : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  BarbNumber        : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
  Levels          : {1:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},2:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},3:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},4:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},5:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},6:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},7:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false},8:{0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false,9:false,10:false}},
  Troops          : {1:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},2:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},3:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},4:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},5:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},6:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},7:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},8:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},9:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0},10:{1:0,2:0,3:0,4:0,5:0,6:0,7:0, 8:0,9:0, 10:0, 11:0, 12:0}},
  MinDistance     : {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0},
  Distance              : {1:750,2:750,3:750,4:750,5:750,6:750,7:750,8:750,9:750,10:750},
  Update                : {1:[0,0],2:[0,0],3:[0,0],4:[0,0],5:[0,0],6:[0,0],7:[0,0],8:[0,0]},
  UpdateEnabled         : true,
  UpdateInterval      : 30,
  stopsearch            : 1,
  knightselector        : 0,
  barbMinKnight     : 56,
  barbMaxKnight     : 250,
};

var ResetAll=false;
var deleting=false;

var ChatOptions = {
  latestChats               : [],
  AllowUsersRemoteControl   : [],
  BlacklistUsersRemoteControl: [],
  password                  : '',
  Chatpassenable            : false,
};

var ApothecaryOptions = {
  Active : false,
  goldkeep : 0,
  city : {0:[],1:[],2:[],3:[],4:[],5:[],6:[],7:[]},
};

var CombatOptions = 
{
  research : [{tch8:0,tch9:0,tch13:0,tch15:0}, //Poison Edge, Metal Alloys, Fletching, Healing Potions
              {tch8:0,tch9:0,tch13:0,tch15:0}],
  knt      : [50,50],
  guardian : [['wood',0],['ore',0]],
  ratio    : [{unt1:{},unt2:{},unt3:{},unt4:{},unt5:{},unt6:{},unt7:{},unt8:{},unt9:{},unt10:{},unt11:{},unt12:{}},
              {unt1:{},unt2:{},unt3:{},unt4:{},unt5:{},unt6:{},unt7:{},unt8:{},unt9:{},unt10:{},unt11:{},unt12:{}}],
};

var troopTypes = {
  1:  'SupplyTroops',
  2:  'Militiaman',
  3:  'Scout',
  4:  'Pikeman',
  5:  'Swordsman',
  6:  'Archer',
  7:  'Cavalry',
  8:  'HeavyCavalry',
  9:  'SupplyWagon',
  10: 'Ballista',
  11: 'BatteringRam',
  12: 'Catapult',
  13: 'Bloodthorn',
  14: 'Executioner',
  15: 'SiegeWall',
}; 

var shortTroops = [ "ST", "MM", "Scout", "Pike", "Sword", "Arch", "LC", "HC", "SW", "Ball", "Ram", "Cat", "BT", "Exe", "SW" ];

var buildingIDs = {
    Farm:1,Mine:4,Quarry:3,Sawmill:2,Castle:0,Wall:19,Barracks:13,Cottage:5,RelStat:18,Stable:17,Blacksmith:15,KnightsHall:7,Workshop:16,FeySpire:20,Apothecary:21,RallyPoint:12,Embassy:8,AlcLab:11,Nothing:0,Wall:19
    };
var buildingTypes = {
    type5:"Cottage",type6:"",type7:"KnightsHall",type8:"Embassy",type9:"",type10:"",type11:"AlcLab",type12:"RallyPoint",type13:"Barracks",type14:"WatchTower",type15:"Blacksmith",type16:"Workshop",type17:"Stable",type18:"RelStation",type19:"Wall",type20:"FeySpire",type21:"Apothecary",
};
var cityBuildingNames = {
    Wall:"Wall",Cottage:"Cottage",Barracks:"Barracks",Blacksmith:"Blacksmith",Stable:"Stable",Apothecary:"Apothecary",Workshop:"Workshop",FeySpire:"Fey Spire",Embassy:"Embassy",RelStation:"Relief Station",AlcLab:"Alchemy Lab",WatchTower:"Watch Tower",KnightsHall:"Knights Hall",RallyPoint:"Rally Point",
    };
var fieldBuildingNames = {
    Farm:"Farm",Mine:"Mine",Sawmill:"Mill",Quarry:"Quarry",
    };
var ascendedLayout1Options = {
    "pos1":"Wall","pos2":"Cottage","pos3":"Barracks","pos4":"Barracks","pos5":"Cottage","pos6":"Cottage","pos7":"Barracks","pos8":"Barracks","pos9":"Barracks","pos10":"Barracks","pos11":"Barracks","pos12":"Cottage","pos13":"Cottage","pos14":"Barracks","pos15":"Barracks","pos16":"Barracks","pos17":"WatchTower","pos18":"Barracks","pos19":"Barracks","pos20":"Barracks","pos21":"Cottage","pos22":"Cottage","pos23":"Embassy","pos24":"FeySpire","pos25":"Barracks","pos26":"Barracks","pos27":"Barracks","pos28":"KnightsHall","pos29":"RallyPoint","pos30":"Barracks","pos31":"Barracks","pos32":"Barracks"
    };
var ascendedLayout2Options = {
    "pos1":"Wall","pos2":"Barracks","pos3":"Cottage","pos4":"Cottage","pos5":"Cottage","pos6":"Cottage","pos7":"Cottage","pos8":"Cottage","pos9":"Cottage","pos10":"Cottage","pos11":"Cottage","pos12":"Cottage","pos13":"Cottage","pos14":"Cottage","pos15":"Cottage","pos16":"Cottage","pos17":"WatchTower","pos18":"Cottage","pos19":"Cottage","pos20":"Cottage","pos21":"Cottage","pos22":"Cottage","pos23":"Embassy","pos24":"FeySpire","pos25":"Cottage","pos26":"Cottage","pos27":"Cottage","pos28":"KnightsHall","pos29":"RallyPoint","pos30":"Cottage","pos31":"Cottage","pos32":"Cottage"
    };
var layoutOptions = {
    "pos1":"Wall","pos2":"Cottage","pos3":"Barracks","pos4":"Barracks","pos5":"Cottage","pos6":"Cottage","pos7":"Barracks","pos8":"Barracks","pos9":"Barracks","pos10":"Barracks","pos11":"Barracks","pos12":"Cottage","pos13":"Cottage","pos14":"Barracks","pos15":"Barracks","pos16":"Barracks","pos17":"WatchTower","pos18":"Barracks","pos19":"Barracks","pos20":"Barracks","pos21":"Cottage","pos22":"Cottage","pos23":"Embassy","pos24":"FeySpire","pos25":"Barracks","pos26":"Barracks","pos27":"Barracks","pos28":"KnightsHall","pos29":"RallyPoint","pos30":"Barracks","pos31":"Barracks","pos32":"Barracks"
    };
var fieldlayoutOptions = {
    pos100:"Farm",pos101:"Sawmill",pos104:"Quarry",pos105:"Mine",pos102:"Mine",pos103:"Mine",pos106:"Mine",pos107:"Mine",pos108:"Mine",pos109:"Mine",pos110:"Mine",pos111:"Mine",pos112:"Mine",pos113:"Mine",pos114:"Mine",pos115:"Mine",pos116:"Mine",pos117:"Mine",pos118:"Mine",pos119:"Mine",pos120:"Mine",pos121:"Mine",pos122:"Mine",pos123:"Mine",pos124:"Mine",pos125:"Mine",pos126:"Mine",pos127:"Mine",pos128:"Mine",pos129:"Mine",pos130:"Mine",pos131:"Mine",pos132:"Mine",pos133:"Mine",pos134:"Mine",pos135:"Mine",pos136:"Mine",pos137:"Mine",pos138:"Mine",pos139:"Mine",pos142:"Mine"
    };  
var quickAddBuildings = {
  all:"All",
  barracks:"Barracks",
  cottages:"Cottages",
}
var buildTabTypes = {
  type1: "Farm",
  type2: "Sawmill",
  type3: "Quarry",
  type4: "Mine",
  type5: "Cottage",
  type7: "Knights Hall",
  type8: "Embassy",
  type11: "Alchemy Lab",
  type12: "Rally Point",
  type13: "Barracks",
  type15: "Blacksmith",
  type16: "Workshop",
  type17: "Stable",
  type18: "Relief Station",
  type19: "Wall",
  type20: "FeySpire",
  type21: "Apothecary",
  type0: "Castle"
};

// Get element by id shortform with parent node option
function $(ID,root) {return (root||document).getElementById(ID);}

var nHtml={
  FindByXPath:function(obj,xpath,nodetype) {
  if(!nodetype){
    nodetype = XPathResult.FIRST_ORDERED_NODE_TYPE;
  }
  try {
    var q=document.evaluate(xpath,obj,null,nodetype,null);
  } catch(e) {
    GM_log('bad xpath:'+xpath);
  }
  if(nodetype == XPathResult.FIRST_ORDERED_NODE_TYPE){
    if(q && q.singleNodeValue) { return q.singleNodeValue; }
  }else{
    if(q){
      return q;
    }
  }
  return null;
  },
  
  ClickWin:function(win,obj,evtName) {
  var evt = win.document.createEvent("MouseEvents");
  evt.initMouseEvent(evtName, true, true, win,
    0, 0, 0, 0, 0, false, false, false, false, 0, null);
  return !obj.dispatchEvent(evt);
  },

  Click:function(obj) {
  return this.ClickWin(window,obj,'click');
  },
  
  ClickTimeout:function(obj,millisec) {
  window.setTimeout(function() {
    return nHtml.ClickWin(window,obj,'click');
  },millisec+Math.floor(Math.random()*500));
  },

  SetSelect:function(obj,v) {
  for(var o=0; o<obj.options.length; o++) {
    if(v==obj.options[o].value) { obj.options[o].selected=true; return true; }
  }
  return false;
  },

}

readGlobalOptions ();

if (document.URL.search(/apps.facebook.com\/kingdomsofcamelot/i) >= 0){
  facebookInstance ();
  return;
}
if (document.URL.search(/kabam.com\/kingdoms-of-camelot\/play/i) >= 0){
  kabamStandAlone ();
  return;
}

if (document.URL.search(/facebook.com/i) >= 0){
  if(document.URL.search(/connect\/uiserver.php/i) >= 0 ||
     document.URL.search(/serverfbml/i) >= 0 ||
     document.URL.search(/dialog\/stream.publish/i) >= 0 ||
     document.URL.search(/dialog\/apprequests/i) >= 0 ||
     document.URL.search(/dialog\/feed/i) >= 0)
    HandlePublishPopup ();
  return;
}
if (document.URL.search(/kingdomsofcamelot.com/i) >= 0){
  kocWideScreen ();
}

function kocWideScreen(){
  function setWideFb (){
    try {
      var kocFrame = parent.document.getElementById('kocIframes1');
    }
    catch(e) {
    }
    if (!kocFrame){
      setTimeout (setWideFb, 1000);
      return;
    }
    kocFrame.style.width = '100%';
    var style = document.createElement('style')
    style.innerHTML = 'body {margin:0; width:100%; !important;}';
    kocFrame.parentNode.appendChild(style);
  }
  kocWatchdog ();
  if (GlobalOptions.pbWideScreen)
    setWideFb();
}

var aj2 = function(c, d, b, a)
{
    if (d.ctrl && d.ctrl == "Tracking")
    {
        logit("Tracking intercepted");
        logit("Ajax d: " + uneval(d));
        return;
        //disable - don't send on the message
    }
    else
    {
        unsafeWindow.AjaxCall.gAjaxRequest(c, d, b, a, "post");
    }
}

if(unsafeWindow.AjaxCall)
{
  unsafeWindow.AjaxCall.gPostRequest = aj2;
}

/***  Run only in "apps.facebook.com" instance ... ***/
function facebookInstance (){
  function setWide (){
  var iFrame = document.getElementById('iframe_canvas');
  if (!iFrame){
    setTimeout (setWide, 1000);
    return;
  }
  iFrame.style.width = '100%';

  while ( (iFrame=iFrame.parentNode) != null)
    if (iFrame.tagName=='DIV')
    iFrame.style.width = '100%';
  document.getElementById('globalContainer').style.left = '0px';
    try{    
      document.getElementById('rightCol').parentNode.removeChild(document.getElementById('rightCol'));
      document.getElementById('leftColContainer').parentNode.removeChild(document.getElementById('leftColContainer'));
    } catch (e){
      // toolkit may have removed them already!
    }
    var e = document.getElementById('mainContainer');
  if(e){
    if (GlobalOptions.pbWideScreenStyle=="normal") e.parentNode.style.minWidth = '100%';
    if (GlobalOptions.pbWideScreenStyle=="wide") e.parentNode.style.width = '1520px';
    if (GlobalOptions.pbWideScreenStyle=="ultra") e.parentNode.style.width = '1900px';
    for(i=0; i<e.childNodes.length; i++){
      if(e.childNodes[i].id == 'contentCol'){
        e.childNodes[i].style.margin = '0px';
        e.childNodes[i].style.paddingTop = '5px';
        break;
      }
    }
  }
  var e = document.getElementById('pageHead');
  if(e){
    e.style.width = '80%';
    e.style.margin = '0 10%';
  }
  var e = document.getElementById('bottomContent');
  if(e){
    e.style.padding = "0px 0px 12px 0px";
  }
    
  }
  facebookWatchdog();
  if (GlobalOptions.pbWideScreen)
    setWide();
}

function kabamStandAlone (){
  function setWide (){
    var iFrames = $('game_frame');
  if (!iFrames){
      setTimeout (setWide, 1000);
      return;
    }
    iFrames.style.width = '100%';
    while ( (iFrames=iFrames.parentNode) != null)
      if (iFrames.tagName=='DIV')
      iFrames.style.width = '100%';
    }
    
  function sendmeaway (){
    var serverID = /s=([0-9]+)/im.exec (document.location.href);
    var sr = /signed_request" value="(.*?)"/im.exec ($("post_form").innerHTML);
    var goto = $("post_form").action+(serverID?"?s="+serverID[1]:'');
    var t = '<FORM target="_top" action="'+ goto +'" method=post><INPUT id=xxxpbutExplode type=submit value=RELOAD><INPUT type=hidden name=signed_request value="'+ sr[1] +'" /><INPUT type=hidden name=platform_req value=A /></form>';
    var e = document.createElement ('div');
    e.innerHTML = t;
    document.body.appendChild (e);
    setTimeout (function (){document.getElementById('xxxpbutExplode').click();}, 0);
  }

  if (GlobalOptions.pbWideScreen)
    setWide();
  if(GlobalOptions.pbNoMoreKabam)
    sendmeaway();
}

function HandlePublishPopup() {
    // Check the app id (we only want to handle the popup for kingdoms of camelot)
    var FBInputForm = document.getElementById('uiserver_form');
    //logit("FBInputForm "+FBInputForm);
    if(FBInputForm){
      var channel_input = nHtml.FindByXPath(FBInputForm,".//input[contains(@name,'channel')]");
      //logit("channel_input "+channel_input);
      if(channel_input){
        var current_channel_url = channel_input.value;
        //logit("current_channel_url "+current_channel_url);
        if (current_channel_url.match(/(http|https):\/\/(.*?)\.kingdomsofcamelot\.com(.*?)/i)) {
          var publish_button = nHtml.FindByXPath(FBInputForm,".//input[@type='submit' and contains(@name,'publish')]");
          var cancel_publish_button = nHtml.FindByXPath(FBInputForm,".//input[@type='submit' and contains(@name,'cancel')]");
          var privacy_setting = nHtml.FindByXPath(FBInputForm,".//select[@name='audience[0][value]']");
          //logit("publish_button "+publish_button);
          //logit("privacy_setting "+privacy_setting);
          //logit("cancel_button " + cancel_publish_button);
          if(publish_button && privacy_setting){
            // 80: Everyone
            // 50: Friends of Friends
            // 40: Friends Only
            // 10: Only Me
            privacy_setting.innerHTML = '<option value="'+ GlobalOptions.autoPublishPrivacySetting +'"></option>';
            privacy_setting.selectedIndex = 0;
            if (GlobalOptions.autoPublishGamePopups && !GlobalOptions.autoCancelGamePopups){
              nHtml.Click(publish_button);
            }else if (GlobalOptions.autoCancelGamePopups && !GlobalOptions.autoPublishGamePopups){
              nHtml.Click(cancel_publish_button);
              logit('canceling')
            }
          }
        }
      }   
    }
    setTimeout(HandlePublishPopup, 1000);
  }

var Cities = {};

var Seed = unsafeWindow.seed;
var uW = unsafeWindow;
var CM = unsafeWindow.cm;

var Tabs = {};
var pbButtons = {};

var mainPop;
var pbStartupTimer = null;
var pbPopUpTopClass = 'pbPopTop';
var firefoxVersion = getFirefoxVersion();
var TrainCity = 0;

function pbStartup ()
{
  clearTimeout (pbStartupTimer);
  
  if (unsafeWindow.pbLoaded) 
  {
    return;
  }
  
  var metc = getClientCoords(document.getElementById('main_engagement_tabs'));
  
  if (metc.width==null || metc.width==0) 
  {
    pbStartupTimer = setTimeout (pbStartup, 1000);
    return;
  }
  
  unsafeWindow.pbLoaded = true;
  
  Seed = unsafeWindow.seed;
  readOptions();
  var styles = '.xtab {padding-right: 5px; border:none; background:none; white-space:nowrap;}\
    .xtabBR {padding-right: 5px; border:none; background:none;}\
    .rot45 { transform: rotate(-45deg); -ms-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); -o-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -moz-transform-origin: 50% 50%; z-index: 10;}\
    table.pbTab tr td {border:none; background:none; white-space:nowrap; padding:0px}\
    .hostile td { background:red; }.friendly td{background:lightgreen; }.ally td{background:lightblue; }\
    div.trTitle { text-shadow: 0px 1px 0px white; margin-top: 3px; line-height: 24px; text-align: center; color: #5C3317; font: bold 1.3em Georiga; }\
    div.cardOverlay { font: cracked; width: 100%; font-size:3.5em; position: absolute; left: 0%; top: 30%; color: red; text-align: center; text-shadow: 2px 2px 4px #000;} \
    div.trCloseSpan {float: right; background-image: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/close_icon.png"); background-repeat: no-repeat; height: 20px; width: 20px; }\
    #tr_footer {height: 50px; background: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/dialog_740_r3_c1.jpg") scroll no-repeat center bottom;}\
    table.pbTabPadNW tr td {border:none; background:none; white-space:nowrap; padding: 2px 4px 2px 8px;}\
    table.pbTabBR tr td {border:none; background:none;}\
    table.pbTabLined tr td {border:1px none none solid none; padding: 2px 5px; white-space:nowrap;}\
    table.pbOptions tr td {border:1px none none solid none; padding: 1px 3px; white-space:nowrap;}\
    table.pbSrchResults tr td {border:1px none none solid none; padding: 1px 3px; white-space:nowrap;}\
    table.pbTabSome tr td {border:none; background:none; padding: 1px 3px; white-space:nowrap;}\
    table.pbTabPad tr td { padding-left: 8px;}\
    table.ptNoPad tr td {border:none; background:none; white-space:nowrap; padding:0px}\
    .pbDetLeft {padding:0 5px 0 0 !important; font-weight:bold; text-align:right}\
    .pbStat {border:1px solid; border-color:#000000; font-weight:bold; padding-top:2px; padding-bottom:2px; text-align:center; color:#ffffff ; background-color:#357;}\
    .pbEquip {border:1px solid; border-color:#000000; font-weight:bold; padding-top:2px; padding-bottom:2px; text-align:left; color:#000000 ; background-color:#357;}\
    .pbentry {padding: 7px; white-space:nowrap;}\
    .trStat {border:1px solid; border-color:#000000; font-weight:bold; padding-top:2px; padding-bottom:2px; text-align:center; color:#ffffff ; background-color:#357;}\
    .trentry {padding: 7px; white-space:nowrap;}\
    button::-moz-focus-inner, input[type="submit"]::-moz-focus-inner { border: none; }\
    span.whiteOnRed {padding-left:3px; padding-right:3px; background-color:#700; color:white; font-weight:bold}\
    span.boldRed {color:#800; font-weight:bold}\
    .castleBut {outline:0px; margin-left:0px; margin-right:0px; width:24px; height:26px; font-size:12px; font-weight:bold;}\
    .castleBut:hover {background-image:url("'+ URL_CASTLE_BUT_SEL +'")}\
    .castleButNon {background-image:url("'+ URL_CASTLE_BUT +'")}\
    .castleButSel {background-image:url("'+ URL_CASTLE_BUT_SEL +'")}\
    input.pbDefButOn {cursor:pointer; border:1px solid #45d183;}\
    input.pbDefButOff {cursor:pointer; border:1px solid #f61646;}\
    a.ptButton20 {color:#ffff80}\
    a.button20:hover {color:#000000}\
    table.pbMainTab { empty-cells: show; margin-left: 1px; margin-top: 1px; padding: 1px;  padding-left:1px;}\
    table.pbMainTab tr td a {color:inherit }\
    table.pbMainTab tr td   {height:60%; empty-cells:show; padding: 0px 4px 0px 4px;  margin-top:5px; white-space:nowrap; border: 1px solid; border-style: none none solid none;}\
    table.pbMainTab tr td.spacer {padding: 0px 0px;}\
    table.pbMainTab tr td.notSel { color: #ffffff; font-size: 12px; font-weight:bold; text-shadow: -1px 1px 3px #666666; border: solid #615461 1px; background: -moz-linear-gradient(top, #6ff28e, #196b2c);}\
    table.pbMainTab tr td.sel { color: #000000; font-size: 12px; font-weight:bold;  text-shadow: -1px 1px 3px #CECECE; border: solid #615461 1px; background: -moz-linear-gradient(top, #6ff28e, #196b2c);}\
    table.pbMainTab tr td:hover { color: #191919; font-size: 12px; font-weight:bold; text-shadow: -1px 1px 3px #CECECE; background: -moz-linear-gradient(top, #43cc7e, #20a129)}\
    table.trStatTab tr td { background-color: #ffffff; white-space:nowrap; min-width:50px; padding:5px; border-bottom:solid black 1px;}\
    table.trStatTab tr td:last-child { border-right:solid black 1px; }\
    table.trStatTab tr:first-child th { border-top:solid black 1px; }\
    table.trStatTab tr td.td0 { background-color: white; }\
    table.trStatTab tr td.redLine {background-color:#FF5C33; color:black;}\
    table.trStatTab tr td.yellowLine { background-color:#FFFF00; color:black;}\
    table.trStatTab tr td.orangeLine { background-color:#FF7519; color:black;}\
    table.trStatTab tr td.greenLine { background-color:#47D147; color:black;}\
    table.trStatTab tr td.blueLine { background-color:#7094FF; color:black;}\
    table.trStatTab tr td.td1 { background-color: #eeeeee; }\
    table.trStatTab tr td.td2 { background-color: white; }\
    table.pbReassign tr td { padding: 1px 3px; } \
    table.pbReassign tr:nth-child(odd) td  { background-color:#888; } \
    table.pbReassign tr:nth-child(even) td  { background-color:#fff; } \
    table.trStatTab tr th {border:solid black 1px; border-top: none; background-color: #357; color: white; white-space:nowrap; padding:5px}\
    table.trTabLined tr td {border:1px none none solid none; padding: 2px 5px; white-space:nowrap;}\
    table.trOptions tr td {border:1px none none solid none; padding: 1px 3px; white-space:nowrap;}\
    table.trSrchResults tr td {border:1px none none solid none; padding: 1px 3px; white-space:nowrap;}\
    table.trTabSome tr td {border:none; background:none; padding: 1px 3px; white-space:nowrap;}\
    table.trTabPad2 tr td { padding-left: 20px; background: none;}\
    table.Throne {background-color:#FFFFE3; white-space:nowrap; padding:0px; border-style:solid; border-color:darkgrey; width:250px; max-width:250px; text-wrap:normal;word-wrap:break-word}\
    table.Throne tr td {background:none; white-space:nowrap; padding:0px; border-style:none;}\
    table.ThroneEQ {background-color:#FFFFE3; white-space:nowrap; padding:0px; border-style:solid; border-color:lightred; width:250px; max-width:250px; text-wrap:normal;word-wrap:break-word}\
    table.ThroneEQ tr td {background:none; white-space:nowrap; padding:0px; border-style:none}\
    tr.pbPopTop td { background-color:transparent; border:none; height: 21px; padding:0px;}\
    tr.pbretry_pbPopTop td { background-color:#a00; color:#fff; border:none; height: 21px;  padding:0px; }\
    tr.pbMainPopTop td { background-color:#ded; border:none; height: 42px; width:80%; padding:0px; }\
    tr.pbretry_pbMainPopTop td { background-color:#a00; color:#fff; border:none; height: 42px;  padding:0px; }\
    .pbPopMain  { border:1px solid #000000; }\
    .pbPopup  {resize:both; border:5px ridge #666; opacity:'+(parseFloat(Options.Opacity)<'0.5'?'0.5':Options.Opacity)+';  }\
    div.pbPopup { background: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/modal/736_bg_tile.jpg") repeat transparent 0% 0%; }\
    div.pbPopup { background: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/dialog_740_r2_c1.jpg") no-repeat transparent 0% 0%; }\
    span.pbTextFriendly {color: #080}\
    span.pbTextHostile {color: #800}\
    .pbButCancel {background-color:#a00; font-weight:bold; color:#fff}\
    div.trCard {width: 200px;}\
    div.trCard div.description>div{width:70px;height:70px; }\
    div.trCard div.description div.briton.advisor{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/briton_advisor_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.briton.banner{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/briton_banner_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.briton.chair{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/briton_chair_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.briton.table{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/briton_table_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.briton.window{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/briton_window_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.briton.trophy{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/briton_trophy_normal_1_5.png") top left no-repeat;}\
    div.trCard div.description div.druid.advisor{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/druid_advisor_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.druid.banner{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/druid_banner_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.druid.chair{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/druid_chair_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.druid.table{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/druid_table_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.druid.window{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/druid_window_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.druid.trophy{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/druid_trophy_normal_1_5.png") top left no-repeat;}\
    div.trCard div.description div.fey.advisor{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/fey_advisor_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.fey.banner{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/fey_banner_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.fey.chair{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/fey_chair_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.fey.table{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/fey_table_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.fey.window{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/fey_window_normal_1.png") top left no-repeat;}\
    div.trCard div.description div.fey.trophy{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/icons/70/fey_trophy_normal_1_5.png") top left no-repeat;}\
    div.trCard{font:bold 12px Georiga; overflow: hidden;}\
    div.trCard>div{float:left;border:1px solid #a56631;margin:0px;padding:0px;width:200px;background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/modal/modal_med_bg_4.png") -200px 0 no-repeat;}\
    div.trCard div.title{height: 35px; font:bold 12px Georgia;border-bottom:1px solid #703200;padding:4px 3px 5px 8px;background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/panel/modal/item_bg.png") -20px -100px no-repeat;}\
    div.trCard div.title span.icon{background:transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/equip.png") top right no-repeat;display:block;height:20px;width:20px;top:12px;right:12px;position:absolute;}\
    div.trCard .disabled{opacity:.5;}\   div.trCard ul{margin:0px;padding:0;list-style:none;}\
    div.trCard li{padding:0px 0 0 0px;color:#3f2300;font-weight:bold;font-size:12px;}\
    div.trCard div.description{overflow:hidden;border-bottom:1px solid #703200;padding:5px 0;}\
    div.trCard div.description{overflow:hidden;border-bottom:1px solid #703200;}\
    div.trCard div.description div.portrait{float:left;}\
    div.trCard div.description div.portrait{border:3px solid #deaf69;margin-right:10px;}\
    div.trCard div.description>ul{float:left;margin:3px 0 0 0;padding:0;}\
    div.trCard div.description>ul li{padding:0;font-weight:bold;font-size:10px;text-transform:capitalize;}\
    div.trRule {border:2px inset #c0c0c0; margin-right:10px; margin-left:10px; margin-bottom:2px; padding-left:5px; padding-bottom:5px} \
    div.trRuleCreate {margin-right:10px; padding-right: 5px; margin-bottom:2px; padding-bottom:5px} \
    div.trRule { background-color: #eeeeee; } \
    div.blueBorder { border: 3px solid blue; } \
    div.blueBorder2 { border: 10px solid blue; } \
    div.greenBorder { border: 3px solid green; } \
    div.greenBorder2 { border: 10px solid green; } \
    div.redBorder { border: 3px solid red; } \
    div.redBorder2 { border: 10px solid red; } \
    div.yellowBorder { outline: 3px solid yellow; outline-offset:0px; }\
    div.yellowBorder2 { outline: 10px solid yellow; outline-offset:0px; }\
    div.trhammer { background-image: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/sm_hammer.png"); background-repeat: no-repeat; background-color: transparent; display: inline-block; width: 28px; height: 32px; margin: 2px; vertical-align: middle;}\
    div.trbroken { background-image: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/sm_fail_overlay.png"); background-repeat: no-repeat; background-color: transparent; display: inline-block; width: 28px; height: 32px; margin: 2px; vertical-align: middle;}\
    div.trsuccess { background-image: url('+ success_image +'); background-repeat: no-repeat; background-color: transparent; display: inline-block; width: 28px; height: 32px; margin: 2px; vertical-align: middle;}\
    div.trup { display=inline;  background-image: url('+ up_img +'); background-repeat: no-repeat; background-color: transparent;  width: 28px; height: 24px; }\
    span.up { background-size:cover; float:right; display=inline;  background-image: url('+ up_img +'); background-repeat: no-repeat; background:#333;  width: 14px; height: 12px; }\
    span.up:hover { background-size:cover; float:right; display=inline;  background-image: url('+ up_glow +'); background-repeat: no-repeat; background:#333;  width: 14px; height: 12px; }\
    div.trup:hover { display=inline;  background-image: url('+ up_glow +'); background-repeat: no-repeat; background-color: transparent;  width: 28px; height: 24px; }\
    div.trremove { display=inline;  background-image: url('+ remove_img +'); background-repeat: no-repeat; background-color: transparent;  width: 50px; height: 50px; }\
    div.trremove:hover { display=inline;  background-image: url('+ remove_glow +'); background-repeat: no-repeat; background-color: transparent;  width: 50px; height: 50px; }\
    div.trdown { display=inline;  background-image: url('+ down_img +'); background-repeat: no-repeat; background-color: transparent;  width: 28px; height: 24px; }\
    span.down { background-size:cover; float:right; display=inline;  background-image: url('+ down_img +'); background-repeat: no-repeat; background:#333;  width: 14px; height: 12px; }\
    span.down:hover { background-size:cover; float:right; display=inline;  background-image: url('+ down_glow +'); background-repeat: no-repeat; background:#333;  width: 14px; height: 12px; }\
    div.trdown:hover { display=inline;  background-image: url('+ down_glow +'); background-repeat: no-repeat; background-color: transparent;  width: 28px; height: 24px; }\
    div.trgbtn { display=inline;  background-image: url('+ gbtn_img +'); background-repeat: no-repeat; background-color: transparent;  width: 32px; height: 32px; margin: 0px; }\
    div.trPopup { background: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/modal/736_bg_tile.jpg") repeat transparent 0% 0%; }\
    div.trPopup { background: url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/dialog_740_r2_c1.jpg") no-repeat transparent 0% 0%; }\
    tr.trPopTop td { background-color:transparent; border:none; height: 21px;  padding:0px;}\
    tr.trretry_trPopTop td { background-color:#a00; color:#fff; border:none; height: 21px;  padding:0px; }\
    tr.trMainPopTop td { background-color:#ded; border:none; height: 42px;  padding:0px; } \
    tr.trretry_trMainPopTop td { background-color:#a00; color:#fff; border:none; height: 42px;  padding:0px; }\
    .trPopMain  { }\
    .trPopup  {border:3px ridge #666; opacity:'+upgradeData.Opacity+'; }\
    ul#t_throneStatList li { float: left; width: 22px; height: 22px; text-align: center; color: white; }\
    ul#t_throneStatList li.active { background: transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/set_active.png") top left no-repeat; } \
    ul#t_throneStatList li.selected { background: transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/set_selected.png") top left no-repeat; }\
    ul#t_throneStatList li.locked { background: transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/set_locked.png") top left no-repeat; text-indent: -999px; }\
    ul#t_throneStatList li.buy { background: transparent url("https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/set_buy.png") top left no-repeat; text-indent: -999px; }\
    div#range_pop-up { display: none; position: absolute; padding: 10px; background: #eeeeee; color: #000000; border: 1px solid #1a1a1a; font-size: 90%;} \
    #trQueue th { text-align: center; }\
    div.indent25 {padding-left:25px}';
    
  window.name = 'PT';
  logit ("* KOC Power Bot v"+ Version +" Loaded");

  readLanguage();
  readChatOptions();
  readCrestData();
  readTrainingOptions();
  readCombatOptions();
  readAttackOptions();
  readFarmOptions();
  readThroneOptions();
  readUpgradeData();
  readApothecaryOptions();
  readUpgradeStats();
  readPlayerThrone();
  readPlayerThroneItemStats();
  readSalvageData();
  readLayoutOptions();
  
  checkVersion();

  setCities();

  // TODO: Make sure WinPos is visible on-screen ?
  if (Options.pbWinPos==null || Options.pbWinPos.x==null || Options.pbWinPos.x=='' || isNaN(Options.pbWinPos.x)) 
  {
    var c = getClientCoords (document.getElementById('main_engagement_tabs'));
    Options.pbWinPos.x = c.x + 4;
    Options.pbWinPos.y = c.y + c.height;
    saveOptions ();
  }

  // Reset window xPos if the widescreen option is disabled
  if(!GlobalOptions.pbWideScreen && Options.pbWinPos.x > 700) 
  {
    var c = getClientCoords (document.getElementById('main_engagement_tabs'));
    Options.pbWinPos.x = c.x + 4;
    saveOptions ();
  }

  mainPop = new pbPopup ('pb', Options.pbWinPos.x, Options.pbWinPos.y, 850, 1200, Options.pbWinDrag,
      function (){
        tabManager.hideTab();
        Options.pbWinIsOpen = false;
        saveOptions();
      });
  mainPop.autoHeight (true);  

  if(Seed.allianceDiplomacies != undefined && Seed.allianceDiplomacies.allianceId != undefined)
  {
    if(Options.PrevAllianceId == 0) 
    {
      if(Seed.allianceDiplomacies.allianceId != undefined)
      {
        Options.PrevAllianceId = Seed.allianceDiplomacies.allianceId;
        saveOptions();
      }
    }
    else
    {
      if(Options.PrevAllianceId != Seed.allianceDiplomacies.allianceId)
      {
        if(Options.PrevAllianceId == Options.AllianceId)
        {
          Options.AllianceId = Seed.allianceDiplomacies.allianceId;
          Options.PrevAllianceId = Options.AllianceId;
          saveOptions();
        }
        else
        {
          Options.PrevAllianceId = Seed.allianceDiplomacies.allianceId;
          saveOptions();
        }
      }
    }
  }
  if(!Options.FullEnable){Tabs.Range.tabDisabled=true;}
  if(Options.DebugEnable){Tabs.debug.tabDisabled=false;} 
  if(Options.TestEnable){Tabs.Test.tabDisabled=false;} 
  mainPop.getMainDiv().innerHTML = '<STYLE>'+ styles +'</style>';
  AddMainTabLink('BOT', eventHideShow, mouseMainTab);
  tabManager.init (mainPop.getMainDiv());
  actionLog ("KOC Power Bot v"+ Version +" Loaded  (KofC version: "+ anticd.getKOCversion() +")");
  
  FairieKiller.init (Options.pbKillFairie);
  RefreshEvery.init ();
  SpamEvery.init ();
  CollectGold.init();
  FoodAlerts.init();
  ChatPane.init();
  ChatStuff.init();
  DeleteReports.init();
  //DeleteThrone.init();

  if (Options.pbWinIsOpen && Options.pbTrackOpen)
  {
    mainPop.show (true);
    tabManager.showTab();
  }

  window.addEventListener('unload', onUnload, false);
  exportToKOCattack.init();
  WideScreen.init ();
  if(Options.AllianceId==816){Options.AllianceId=507;saveOptions();}
  WideScreen.setChatOnRight (Options.pbChatOnRight);
  WideScreen.useWideMap (Options.pbWideMap);
  setInterval (DrawLevelIcons,1250);
  setTimeout (ScheduleRequest, 5000);
  
  // if our captcha timer did not finish before reset then we need to restore the handling of it
  if(Options.captchaTimer > 0) 
  {
    actionLog('Captcha: lockout remaining - ' + (Options.captchaDuration - Options.captchaTimer + 1) + ' minutes');
    setTimeout(checkCaptcha, 1 * 60 * 1000);
  }

  if(Options.mklag)  
  {
    setInterval(fixkabamlag, 60 * 1000);
    logit("Debug : fix kabam lag issue");
  }
}

/************************ Food Alerts *************************/
var FoodAlerts = {
  init : function (){
    var f = FoodAlerts;
    f.e_eachMinute();
  },

  minuteTimer : null,

  e_eachMinute : function (){  
    var f = FoodAlerts;
    var now = unixTime();
    row = [];

    for(i=0; i < Cities.numCities; i++) {
      var rp = getResourceProduction (Cities.cities[i].id);
      var foodleft = parseInt(Seed.resources["city" + Cities.cities[i].id]['rec1'][0])/3600;
      var usage = rp[1] - parseInt(Seed.resources["city" + Cities.cities[i].id]['rec1'][3]);
      row[i] = rp[1] - usage;
      var timeLeft = parseInt(Seed.resources["city" + Cities.cities[i].id]['rec1'][0]) / 3600 / (0-usage) * 3600;
      var msg = '';
      if (usage < 0) {
        if (Options.pbFoodAlert && timeLeft<(6*3600)) {
          msg += translate("My city")+' '+Cities.cities[i].name.substring(0,10) + ' (' +
            Cities.cities[i].x +','+ Cities.cities[i].y + ')';
          msg += translate("is low on food") + "<br>";
          msg += translate("Food Remaining") + ': ' + addCommas(Math.floor(foodleft))+'<br>';
          msg += translate("Time Remaining") + ': ' + timestrShort(timeLeft)+'<br>';
          msg += translate("Upkeep") + ': ' + addCommas(usage)+'<br>';
          msg += translate("Troops in city")+':<br>';
              
          for(var k in troops){
            var troopCount = parseInt(Seed.units["city" + Cities.cities[i].id]['unt'+k]);
            if(troopCount > 0)
              msg += troops[k] + ": " + addCommas(troopCount) + "<br>";
          }
          
          sendChat ("/a " + msg);
        }
      }
    }
 
    // changed to 10 minute at present for testing was 30
    f.minuteTimer = setTimeout (f.e_eachMinute, 10 * 60 * 1000);
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Farm
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.farm = {
  tabLabel: 'Farm',
  tabOrder : 612,
  myDiv : null,
  MapAjax : new CMapAjax(),
  popFirst : true,
  opt : {},
  nextattack : null,
  updateSeedTimer: null,
  searchRunning : false,
  tilesSearched : 0,
  tilesFound : 0,
  curX : 0,
  curY : 0,
  lastX : 0,
  firstX : 0,
  firstY : 0,
  lastY : 0,
  knt:{},
  helpArray:{},
  FarmArray:{},
  marchArray:[],
  lookup:1,
  city:0,
  deleting:false,
  DipArray: ["friendly","hostile","friendlyToThem","friendlyToYou","neutral","unallied"],
  interval: ["Continuously","1 Hour","2 Hours","3 Hours","6 Hours","12 Hours","24 Hours"],
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init : function (div){
    var t = Tabs.farm;
    t.myDiv = div;

    var m = '<DIV id=pbTowrtDivF class=pbStat>AUTOMATED FARMING FUNCTION</div><TABLE id=pbbarbingfunctions width=100% height=0% class=pbTab><TR align="center">';

    if (FarmOptions.Running == false) {
         m += '<TD><INPUT id=FarmAttSearch type=submit value="Farming = OFF"></td>';
    } else {
      m += '<TD><INPUT id=FarmAttSearch type=submit value="Farming = ON"></td>';
    }

    m +='<TD><INPUT id=pbpaintFarms type=submit value="Show Farms">';
    m += '<SELECT id=pbFarmcity type=list></td></tr></table>'; 
    m += '</tr></table></div>';
    m += '<DIV id=pbTraderDivD class=pbStat>FARMING STATS</div>';
    m += '<TABLE id=pbfarmstats width=95% height=0% class=pbTab><TR align="left"><TR>';

    for(i=0;i<Seed.cities.length;i++){
        m += '<TD>' + Seed.cities[i][1] +'</td>';
    }

    m+='</tr><TR>';

    for(i=0;i<Seed.cities.length;i++){
        m += '<TD><DIV><span id='+ 'pdtotalFarm' + i +'></span></div></td>';
    }

    m+='</tr><TR>';

    for(i=0;i<Seed.cities.length;i++){
        m += '<TD><DIV><span id='+ 'pddataFarm' + i +'></span></div></td>';
    }

    m+='</tr><TR>'

    for(i=0;i<Seed.cities.length;i++){
        m += '<TD><DIV><span id='+ 'pddataFarmarray' + i +'></span></div></td>';
    }
    m+='</tr></table>';
   
    m+='<DIV id=FarmCheck></div>';

    m += '<DIV id=pbTraderDivD class=pbStat>FARMING OPTIONS</div>';
    m += '<TABLE id=pbfarmstats width=90% height=0% class=pbTab>';
    m += '<TR><TD width=180>Keep rallypoint slot(s) free: </td><TD><INPUT id=FarmRallyClip type=text size=2 maxlength=2 value=' + FarmOptions.RallyClip +'></td></tr>';
    m += '<TR><TD>Farm Interval</td><TD><SELECT id=FarmInterval type=list></td></tr>'; 
    m += '<TR><TD>Delete reports:</td><TD><INPUT id=FarmReports type=checkbox '+(FarmOptions.DeleteReports?'CHECKED':'')+'></td><tr>';
    m += '<TR><TD>Search distance:</td><TD><INPUT type=text id=FarmRadius size=3 maxlength=3 value='+ FarmOptions.MaxDistance +'><INPUT id=FarmSearch type=submit value="Search again"></td><tr>';
    m += '<TR><TD>Might:</td>';
    m += '<TD width=50>Min.:<INPUT type=text id=FarmMinMight size=8 maxlength=8 value='+ FarmOptions.MinMight +'></td>';
    m += '<TD>Max.:<INPUT type=text id=FarmMaxMight size=9 maxlength=9 value='+ FarmOptions.MaxMight +'></td></tr>';
    m += '<TR><TD>Farm if inactive for more then: </td>';
    m += '<TD><INPUT type=text id=FarmInactive size=3 value='+ FarmOptions.Inactive +'> days (checked every 6 hours)</td></table>';
    m += '<TABLE id=pbfarmstats width=90% height=0% class=pbTab><TR align="left"><TR><TD width=100>City:</td>';

    for (i=1;i<=Seed.cities.length;i++) {
      m+='<TD class=pbCityEn><INPUT id=CityEnable'+ i +'  type=checkbox '+(FarmOptions.CityEnable[i]?'CHECKED':'')+'>'+ Seed.cities[i-1][1] +'</td>';
    }

    m += '</tr></table><TABLE id=pbfarmstats width=90% height=0% class=pbTab><TR align="left"><TD width=100>City Level:</td>';

    for (i=1;i<=12;i++) {
      m+='<TD class=pbCityOpt><INPUT id=CityLevel'+ i +'  type=checkbox '+(FarmOptions.CityLevel[i]?'CHECKED':'')+'>'+ i +'</td>';
    }

    m += '</tr></table><TABLE id=pbfarmstats width=90% height=0% class=pbTab><TR align="left"><TR><TD width=100>Diplomacy:</td>';

    for (i=0;i<t.DipArray.length;i++) {
      m+='<TD class=pbDipOpt><INPUT id=Diplomacy'+ t.DipArray[i] +'  type=checkbox '+(FarmOptions.Diplomacy[t.DipArray[i]]?'CHECKED':'')+'>'+ t.DipArray[i] +'</td>';
    }

    m+='</tr></table>';
  
    m += '<DIV id=pbTraderDivD class=pbStat>FARMING TROOPS</div>';
    m += '<TABLE id=pbaddreasignroute width=100% height=0% class=pbTab><TR align="center">';
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_50.jpg?6545"></td>';
    m += '<TD>Supply Troop</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_50.jpg?6545"></td>'
    m += '<TD>Militiaman</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_50.jpg?6545"></td>'
    m += '<TD>Scout</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_50.jpg?6545"></td>'
    m += '<TD>Pikeman</td></tr>'
    m += '<TR><TD  class=pbTroopOpt><INPUT id=FarmTroop1  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[1] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop2  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[2] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop3  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[3] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop4  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[4] +'\></td></tr>';
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_50.jpg?6545"></td>';
    m += '<TD>Swordsman</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_50.jpg?6545"></td>'
    m += '<TD>Archer</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_50.jpg?6545"></td>'
    m += '<TD>Cavalry</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_50.jpg?6545"></td>'
    m += '<TD>Heavy Cavalry</td></tr>'
    m += '<TR><TD  class=pbTroopOpt><INPUT id=FarmTroop5  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[5] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop6  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[6] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop7  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[7] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop8  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[8] +'\></td></tr>';
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_50.jpg?6545"></td>';
    m += '<TD>Supply Wagon</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_50.jpg?6545"></td>'
    m += '<TD>Ballista</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_50.jpg?6545"></td>'
    m += '<TD>Battering Ram</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_50.jpg?6545"></td>'
    m += '<TD>Catapult</td></tr>'
    m += '<TR><TD  class=pbTroopOpt><INPUT id=FarmTroop9  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[9] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop10  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[10] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop11  type=text size=10 maxlength=10 value='+ FarmOptions.Troops[11] +'\></td>';
    m += '<TD  class=pbTroopOpt><INPUT id=FarmTroop12 type=text size=10 maxlength=10 value='+ FarmOptions.Troops[12] +'\></td></tr></table>';
    
    t.myDiv.innerHTML = m;
    t.checkFarmData();
    if(t.nextattack == null) {
      t.nextattack = setInterval(t.getnextCity, FarmOptions.SendInterval*1000);
    }
    
    setInterval(t.startdeletereports,(120000));
    setInterval( t.checkMarches ,2000);
    document.getElementById('pbFarmcity').options.length=0;
    
    for (i=0;i<Seed.cities.length;i++){
      var o = document.createElement("option");
      o.text = Seed.cities[i][1]
      o.value = i+1;
      document.getElementById("pbFarmcity").options.add(o);
    }
    document.getElementById('FarmInterval').options.length=0;

    for (i=0;i<t.interval.length;i++){
      var o = document.createElement("option");
      o.text = t.interval[i];
      o.value = i;
      document.getElementById("FarmInterval").options.add(o);
    }
    document.getElementById('FarmInterval').value = FarmOptions.Interval; 
    for(i=0;i<Seed.cities.length;i++){
      var elem = 'pdtotalFarm'+i;
      if (t.FarmArray[i+1] == undefined) document.getElementById(elem).innerHTML = 'No Data';
      else document.getElementById(elem).innerHTML =  'Farms :' + t.FarmArray[i+1].length +'/'+ t.helpArray[i+1].length;
    }
    document.getElementById('FarmInterval').addEventListener('change', function(){
      FarmOptions.Interval = document.getElementById('FarmInterval').value;
      saveFarmOptions();
    } , false);
    document.getElementById('FarmRallyClip').addEventListener('change', function(){
      FarmOptions.RallyClip = document.getElementById('FarmRallyClip').value;
      saveFarmOptions();
    }, false);
    document.getElementById('FarmReports').addEventListener('change', function(){
      FarmOptions.DeleteReports = document.getElementById('FarmReports').checked;
      saveFarmOptions();
    }, false);
    document.getElementById('FarmRadius').addEventListener('change', function(){
      FarmOptions.MaxDistance = parseInt(document.getElementById('FarmRadius').value);
      saveFarmOptions();
    }, false);
    document.getElementById('FarmAttSearch').addEventListener('click', function(){t.toggleBarbState(this)} , false);
    document.getElementById('FarmSearch').addEventListener('click', function(){
      for (i=1;i<=Seed.cities.length;i++) GM_deleteValue('Farms_' + Seed.player['name'] + '_city_' + i + '_' + getServerId());
      for(i=0;i<Seed.cities.length;i++){
        var elem = 'pdtotalFarm'+i;
        document.getElementById(elem).innerHTML = 'No Data';
      }
      t.checkFarmData();
    } , false);
    document.getElementById('pbpaintFarms').addEventListener('click', function(){t.showFarms(document.getElementById("pbFarmcity").value,Seed.cities[document.getElementById("pbFarmcity").value -1][1]);},false);  
  
    document.getElementById('FarmMinMight').addEventListener('change', function(){
      FarmOptions.MinMight = parseInt(document.getElementById('FarmMinMight').value);
      t.FilterFarms();
      saveFarmOptions(); 
    } , false);
    document.getElementById('FarmMaxMight').addEventListener('change', function(){
      FarmOptions.MaxMight = parseInt(document.getElementById('FarmMaxMight').value);
      t.FilterFarms();
      saveFarmOptions(); 
    } , false);
    document.getElementById('FarmInactive').addEventListener('change', function(){
      FarmOptions.Inactive = parseInt(document.getElementById('FarmInactive').value);
      t.FilterFarms();
      saveFarmOptions(); 
    } , false);
  
    var element = document.getElementsByClassName('pbTroopOpt');
    for (k=0;k<element.length;k++){
      element[k].addEventListener('change', function(){
        for (i=1;i<=10;i++){
          FarmOptions.Troops[i] = document.getElementById('FarmTroop' + i).value;
          saveFarmOptions(); 
        }
      }, false);
    }
  
    element = document.getElementsByClassName('pbCityOpt');
    for (k=0;k<element.length;k++){
        element[k].addEventListener('change', function(){
          for (i=1;i<=12;i++){
            FarmOptions.CityLevel[i] = document.getElementById('CityLevel' + i).checked;
                  saveFarmOptions(); 
          }
          t.FilterFarms();
      }, false);
    }
  
  element = document.getElementsByClassName('pbCityEn');
   for (k=0;k<element.length;k++){
        element[k].addEventListener('change', function(){
          for (i=1;i<=Seed.cities.length;i++){
            FarmOptions.CityEnable[i] = document.getElementById('CityEnable' + i).checked;
                  saveFarmOptions(); 
          }
          t.FilterFarms();
      }, false);
    }
  
  element = document.getElementsByClassName('pbDipOpt');
   for (k=0;k<element.length;k++){
        element[k].addEventListener('change', function(){
          for (i=0;i<t.DipArray.length;i++){
            FarmOptions.Diplomacy[t.DipArray[i]] = document.getElementById('Diplomacy' + t.DipArray[i]).checked;
                  saveFarmOptions();
          }
          t.FilterFarms();
      }, false);
      
    }
  
   },
   

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkMarches: function () 
  {
    var t = Tabs.farm;

    for (i=0;i<FarmOptions.FarmMarches.length;i++)
    {
      var cityId = "city"+ FarmOptions.FarmMarches[i]["cityId"];
      var city = FarmOptions.FarmMarches[i]["city"];
      var marchId = "m" + FarmOptions.FarmMarches[i]["marchId"];

      if (Seed.queue_atkp[cityId][marchId] !=undefined)
      {
        if (Seed.queue_atkp[cityId][marchId].marchStatus == 8  && Seed.queue_atkp[cityId][marchId].hasUpdated) 
        {
          FarmOptions.Checks++;
          saveFarmOptions();
          document.getElementById('FarmCheck').innerHTML = "Attacks: " + FarmOptions.Attacks + " - Checks:" + FarmOptions.Checks;

          for(u=1;u<=12;u++) if (parseInt(Seed.queue_atkp[cityId][marchId]["unit"+u+"Return"]) < parseInt(Seed.queue_atkp[cityId][marchId]["unit"+u+"Count"]))
          {
            t.FarmArray[FarmOptions.FarmMarches[i]["city"]][FarmOptions.FarmMarches[i]["number"]]["lost"] = true;
            t.FarmArray[FarmOptions.FarmMarches[i]["city"]][FarmOptions.FarmMarches[i]["number"]]["enabled"] = false;
          }

          for (a=0;a<t.helpArray[FarmOptions.FarmMarches[i]["city"]].length;a++)
          {
            for (b=0;b<t.FarmArray[FarmOptions.FarmMarches[i]["city"]].length;b++)
            {
              if (parseInt(t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['x']) == parseInt(t.helpArray[FarmOptions.FarmMarches[i]["city"]][b]['x']) && parseInt(t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['y']) == parseInt(t.helpArray[FarmOptions.FarmMarches[i]["city"]][b]['y']))
              {
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['gold'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['gold'];
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['resource1'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['resource1'];
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['resource2'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['resource2'];
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['resource3'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['resource3'];
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['resource4'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['resource4'];
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['empty'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['empty'];
                t.helpArray[FarmOptions.FarmMarches[i]["city"]][a]['lost'] = t.FarmArray[FarmOptions.FarmMarches[i]["city"]][b]['lost'];
              }    
            }
          }

          GM_setValue('Farms_' + Seed.player['name'] + '_city_' + FarmOptions.FarmMarches[i]["city"] + '_' + getServerId(), JSON2.stringify(t.helpArray[FarmOptions.FarmMarches[i]["city"]]));
          FarmOptions.FarmMarches.splice(i,1);
          saveFarmOptions();
        }
      } 
      else 
      {
        FarmOptions.FarmMarches.splice(i,1);
        saveFarmOptions();
      } 
    }
  },  
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkInactives : function (citynumber,city,FarmNumber,xcoord,ycoord,kid,uid,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12)
  {
    var t = Tabs.farm;
    var now = new Date().getTime()/1000.0;
    var hours = (now - t.FarmArray[city][FarmOptions.FarmNumber[city]]['LastCheck']) / 3600;
    if (t.FarmArray[city][FarmOptions.FarmNumber[city]]['DaysInactive'] == "?" || hours > 6)
    {
      var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
      params.pid = uid;
      new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/viewCourt.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        
        onSuccess: function (transport) 
        {
          var rslt = eval("(" + transport.responseText + ")");
          var lastLogin = rslt.playerInfo.lastLogin;
          var fullDate = lastLogin.substr(0,4) +", "+ lastLogin.substr(5,2) +", "+ lastLogin.substr(8,2) ;
          var time = new Date (fullDate).getTime()/1000;
          var days = Math.floor((now - time) / 86400); 
          t.FarmArray[city][FarmOptions.FarmNumber[city]]['DaysInactive'] = days;
          
          for (i=0;i<t.helpArray[city].length;i++)
          {
            if (xcoord == parseInt(t.helpArray[city][i]['x']) && ycoord == parseInt(t.helpArray[city][i]['y']))
            {
             t.helpArray[city][i]['DaysInactive'] = days;
             t.helpArray[city][i]['LastCheck'] = now;
            }    
          }
          GM_setValue('Farms_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.helpArray[city]));
          
          if (days > FarmOptions.Inactive) 
          {
            t.doBarb(citynumber,city,FarmNumber,xcoord,ycoord,kid,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12);
          } 
          else  
          {
            FarmOptions.FarmNumber[city]++;
            saveFarmOptions();
            t.barbing();
          }
        },
        
        onFailure: function (rslt) 
        {
          notify (rslt);
        },
      });
    } 
    else 
    {
      if (t.FarmArray[city][FarmOptions.FarmNumber[city]]['DaysInactive'] > FarmOptions.Inactive) 
      {
        t.doBarb(citynumber,city,FarmNumber,xcoord,ycoord,kid,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12);
      }   
      else
      {
        FarmOptions.FarmNumber[city]++;
        saveFarmOptions();
        t.barbing();
      }
    }
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  showFarms: function (citynumber,cityname) 
  {
    var t = Tabs.farm;
    var popTradeRoutes = null;
    t.popTradeRoutes = new pbPopup('pbShowFarms', 0, 0, 1100, 485, true, function() {clearTimeout (1000);});
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbShowBarbs" id="pbBars">';       
    t.popTradeRoutes.getMainDiv().innerHTML = '</table></div>' + m;
    t.popTradeRoutes.getTopDiv().innerHTML = '<TD><center><B>Farms for city: '+cityname+'</center></td>';
    t.paintFarms(citynumber,cityname);
    t._addTabHeader(citynumber,cityname);
    t.popTradeRoutes.show(true) ;
  },
  
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  ToggleFarms: function(citynumber) 
  {
    var t = Tabs.farm;
    var id=0;
    var element_class = document.getElementsByClassName('Farm');
    for (d = 1; d <= t.FarmArray[citynumber].length; d++) 
    {
      id = d-1;
      var ele = document.getElementById('FarmToggle' + d);
      
      if (ele.checked) 
      {
        t.FarmArray[citynumber][id].enabled = true;
        t.FarmArray[citynumber][id].lost = false;
        t.FarmArray[citynumber][id].empty = 0;   
      }
      else 
        t.FarmArray[citynumber][id].enabled = false;
    }
    
    for (i=0;i<t.helpArray[citynumber].length;i++)
    {
      for (j=0;j<t.FarmArray[citynumber].length;j++)
      {
          if (parseInt(t.FarmArray[citynumber][j]['x']) == parseInt(t.helpArray[citynumber][i]['x']) && parseInt(t.FarmArray[citynumber][j]['y']) == parseInt(t.helpArray[citynumber][i]['y'])) 
            t.helpArray[citynumber][i].enabled = t.FarmArray[citynumber][j].enabled;
      }
    }
    GM_setValue('Farms_' + Seed.player['name'] + '_city_' + citynumber + '_' + getServerId(), JSON2.stringify(t.helpArray[citynumber]));
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintFarms: function(i,cityname)
  {
    var t = Tabs.farm;
    
    for (k=(t.FarmArray[i].length-1);k>=0;k--) 
    { 
      t._addTab(i,cityname,k+1,t.FarmArray[i][k]['enabled'], t.FarmArray[i][k]['x'], t.FarmArray[i][k]['y'],t.FarmArray[i][k]['dist'], t.FarmArray[i][k]['level'],t.FarmArray[i][k]['AllianceName'], t.FarmArray[i][k]['Diplomacy'], t.FarmArray[i][k]['PlayerName'], t.FarmArray[i][k]['cityName'],t.FarmArray[i][k]['might'], t.FarmArray[i][k]['cityNumber'], t.FarmArray[i][k]['attacked'],t.FarmArray[i][k]['DaysInactive'],t.FarmArray[i][k]['lost'],t.FarmArray[i][k]['empty'],t.FarmArray[i][k]['gold'],t.FarmArray[i][k]['resource1'],t.FarmArray[i][k]['resource2'],t.FarmArray[i][k]['resource3'],t.FarmArray[i][k]['resource4']);
    }
  },


  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _addTab: function(citynumber,cityname,queueId,status,X,Y,dist,level,AllianceName,diplomacy,playerName,cityName,might,cityNumber,attacked,DaysInactive,lost,empty,gold,rec1,rec2,rec3,rec4)
  {
    var t = Tabs.farm;
    var row = document.getElementById('pbBars').insertRow(0);
    row.vAlign = 'top';  
  
    if (lost) 
    {
      row.style.color = "red";
    }
    
    if (!lost && empty == 0) 
    {
      row.style.color = "black";
    }
    
    if (FarmOptions.Inactive > DaysInactive) 
    {
      row.style.color = "orange";
    }

    row.insertCell(0).innerHTML = queueId;
    row.insertCell(1).innerHTML = coordLink(X,Y);
    row.insertCell(2).innerHTML = dist;
    row.insertCell(3).innerHTML = level;
    row.insertCell(4).innerHTML = AllianceName;
    row.insertCell(5).innerHTML = diplomacy;    
    row.insertCell(6).innerHTML = playerName;
    row.insertCell(7).innerHTML = cityName;
    row.insertCell(8).innerHTML = addCommas(might);
    row.insertCell(9).innerHTML = DaysInactive;
    row.insertCell(10).innerHTML = attacked;
    row.insertCell(11).innerHTML = '<INPUT class=Farm id="FarmToggle' + queueId + '" type=checkbox>';
         
    var element_class = document.getElementsByClassName('Farm');
    
    for (c = 0; c < element_class.length; c++) 
    {
      element_class[c].checked = t.FarmArray[citynumber][c].enabled;
      element_class[c].addEventListener('click', function(){t.ToggleFarms(citynumber)}, false);
    }
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _addTabHeader: function(citynumber,cityname) 
  {
    var t = Tabs.farm;
    var row = document.getElementById('pbBars').insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = "Id";
    row.insertCell(1).innerHTML = "Coords";
    row.insertCell(2).innerHTML = "Dist.";
    row.insertCell(3).innerHTML = "Level";
    row.insertCell(4).innerHTML = "Allaince Name";
    row.insertCell(5).innerHTML = "Diplomacy";
    row.insertCell(6).innerHTML = "Player Name";
    row.insertCell(7).innerHTML = "City Name";
    row.insertCell(8).innerHTML = "Might";
    row.insertCell(9).innerHTML = "Inactive";
    row.insertCell(10).innerHTML = "# Attacks";
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  startdeletereports : function ()
  {
    var t = Tabs.farm;
    
    if (!FarmOptions.DeleteReports) 
      return;
    
    if(!t.deleting)
    {
      t.deleting = true;
      t.fetchbarbreports(0, t.checkbarbreports);
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fetchbarbreports : function (pageNo, callback)
  {
    var t = Tabs.farm;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    if(pageNo > 0)
      params.pageNo = pageNo;
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/listReports.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) 
      {
        callback(rslt);
      },
      
      onFailure: function () 
      {
      },
    });
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkbarbreports : function (rslt)
  {
    var t = Tabs.farm;
    if(!rslt.ok){
      return;
    }
    if(rslt.arReports.length < 1){
      return;
    }
    var reports = rslt.arReports;
    var totalPages = rslt.totalPages;
    var deletes1 = new Array();
    
    for(k in reports)
    {
      for (i=1;i<=Seed.cities.length;i++)
      {
        var x=Seed.cities[i-1]["2"];
        var y=Seed.cities[i-1]["3"];
        for (j=0;j<t.FarmArray[i].length;j++)
        {
              if (reports[k].side1XCoord == x && reports[k].side1YCoord == y && reports[k].side0XCoord == t.FarmArray[i][j]["x"] && reports[k].side0YCoord == t.FarmArray[i][j]["y"]) deletes1.push(k.substr(2));
        }
      } 
    }
    
    if(deletes1.length > 0)
    {
      t.deletereports(deletes1);
    } 
    else 
    {
      t.deleting = false;
      return;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  deletereports : function (deletes1)
  {
    var t = Tabs.farm;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.s1rids = deletes1.join(",");
    params.s0rids = '';
    params.cityrids = '';
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/deleteCheckedReports.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      
      onSuccess: function (rslt) 
      {
        Seed.newReportCount = parseInt(Seed.newReportCount) - parseInt(deletes1.length);
        t.fetchbarbreports(0, t.checkbarbreports);
      },
      
      onFailure: function () 
      {
      },
    });
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  isMyself: function(userID)
  {
    if(!Seed.players["u"+userID])
      return false;
    if(Seed.players["u"+userID].n == Seed.player.name)
      return true;
    else
      return false;
    return false;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkFarmData: function()
  {
    if(!FarmOptions.Running)
    {
      return;
    }

    var t = Tabs.farm;
    for (i=1;i<=Seed.cities.length;i++)
    {
      t.helpArray[i] = [];
      
      if(!FarmOptions.CityEnable[i])
      {
        continue;
      }

      var myarray = (GM_getValue('Farms_' + Seed.player['name'] + '_city_' + i + '_' + getServerId()));
      
      if (myarray == undefined && t.searchRunning==false) 
      {
        t.searchRunning = true;
        t.lookup=i;
        t.opt.startX=parseInt(Seed.cities[(i-1)][2]);
        t.opt.startY=parseInt(Seed.cities[(i-1)][3]);  
        t.clickedSearch();
      }
      
      if (myarray != undefined)
      {
        myarray = JSON2.parse(myarray);
        //if(AttackOptions.Method == 'distance') 
        t.helpArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['dist'];b = b['dist'];return a == b ? 0 : (a < b ? -1 : 1);});
        //if(AttackOptions.Method == 'level') t.helpArray[i] = myarray.sort(function function (a,b) {a = parseInt(a['level']);b = parseInt(b['level']);return (a > b )? -1 : ((a < b ? 1 : t.SortDist(a,b)));});
        //if(AttackOptions.Method == 'lowlevel') t.helpArray[i] = myarray.sort(function function (a,b) {a = parseInt(a['level']);b = parseInt(b['level']);return (a < b )? -1 : ((a > b ? 1 : t.SortDist(a,b)));});
        GM_setValue('Farms_' + Seed.player['name'] + '_city_' + i + '_' + getServerId(), JSON2.stringify(t.helpArray[i]));
      }
    }
    t.FilterFarms();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  FilterFarms: function() 
  {
    var t = Tabs.farm;
    
    if (t.searchRunning) 
      return;
    
    t.FarmArray = new Array();
    t.FarmArray["1"] = new Array();
    t.FarmArray["2"] = new Array();
    t.FarmArray["3"] = new Array();
    t.FarmArray["4"] = new Array();
    t.FarmArray["5"] = new Array();
    t.FarmArray["6"] = new Array();
    t.FarmArray["7"] = new Array();
    t.FarmArray["8"] = new Array(); 
    
    for (u=1;u<=Seed.cities.length;u++)
    {   
      for (i=0;i<t.helpArray[u].length;i++)
      {
        var checkLvl = false;
        var checkMight = false;
        var checkDip = false;
        var checkAlliance = false;
        var AllianceName = "";
        for (j=1;j<=12;j++) if (FarmOptions.CityLevel[j] && t.helpArray[u][i].level == j) checkLvl=true;
        if (Seed.allianceDiplomacies.allianceName != undefined) AllianceName = Seed.allianceDiplomacies.allianceName;
        if (t.helpArray[u][i].AllianceName != AllianceName) checkAlliance = true;
        if (t.helpArray[u][i].might >= FarmOptions.MinMight && t.helpArray[u][i].might <= FarmOptions.MaxMight) checkMight = true;
        for (j in FarmOptions.Diplomacy) if (FarmOptions.Diplomacy[j] && t.helpArray[u][i].Diplomacy == j) checkDip=true;
        if (checkLvl && checkMight && checkDip && checkAlliance) t.FarmArray[u].push (t.helpArray[u][i]);
      }
      var elem = 'pdtotalFarm'+(u-1);
      if (t.FarmArray[u] == undefined) document.getElementById(elem).innerHTML = 'No Data';
      else document.getElementById(elem).innerHTML =  'Farms :' + t.FarmArray[u].length +'/'+ t.helpArray[u].length;
    }
  },


  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  SortDist: function(a,b) 
  {
    a = parseFloat(a['dist']);
    b = parseFloat(b['dist']);
    
    return (a < b )? -1 : ((a > b ? 1 : 0));
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  toggleBarbState: function(obj)
  {
    var t = Tabs.farm;
    
    if (FarmOptions.Running == true) 
    {
      FarmOptions.Running = false;
      obj.value = "Farm = OFF";
      saveFarmOptions();
      t.nextattack = null;
      t.updateSeedTimer = null;
    } 
    else 
    {
      FarmOptions.Running = true;
      obj.value = "Farm = ON";
      saveFarmOptions();
      t.checkFarmData();
      t.nextattack = setInterval(t.getnextCity,(FarmOptions.SendInterval*1000));
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  barbing : function()
  {
    var t = Tabs.farm;
    var city = t.city;
    var u1 = FarmOptions.Troops[1];
    var u2 = FarmOptions.Troops[2];
    var u3 = FarmOptions.Troops[3];
    var u4 = FarmOptions.Troops[4];
    var u5 = FarmOptions.Troops[5];
    var u6 = FarmOptions.Troops[6];
    var u7 = FarmOptions.Troops[7];
    var u8 = FarmOptions.Troops[8];
    var u9 = FarmOptions.Troops[9];
    var u10 = FarmOptions.Troops[10];
    var u11 = FarmOptions.Troops[11];
    var u12 = FarmOptions.Troops[12];
    var now = new Date().getTime()/1000.0;
    now = now.toFixed(0);

    citynumber = Seed.cities[city-1][0];
    cityID = 'city' + citynumber; 

    rallypointlevel = getRallypointLevel(cityID);
    var freeMarchSlots = getFreeMarchSlots(cityID);
    
    var element2 = 'pddataFarmarray' + (city - 1); 
    document.getElementById(element2).innerHTML =  'RP: (' + freeMarchSlots + '/' + rallypointlevel +')';
     
    if (!FarmOptions.CityEnable[city]) 
    {
      return;
    }
    
    if (freeMarchSlots <= FarmOptions.RallyClip) 
    {
      return;
    }
    
    if (u1 > parseInt(Seed.units[cityID]['unt1']) || u2 > parseInt(Seed.units[cityID]['unt2']) || u3 > parseInt(Seed.units[cityID]['unt3']) 
     || u4 > parseInt(Seed.units[cityID]['unt4']) || u5 > parseInt(Seed.units[cityID]['unt5']) || u6 > parseInt(Seed.units[cityID]['unt6']) 
     || u7 > parseInt(Seed.units[cityID]['unt7']) || u8 > parseInt(Seed.units[cityID]['unt8']) || u9 > parseInt(Seed.units[cityID]['unt9']) 
     || u10 > parseInt(Seed.units[cityID]['unt10']) || u11 > parseInt(Seed.units[cityID]['unt11']) || u12 > parseInt(Seed.units[cityID]['unt12'])) 
    {
      return;
    }
    
    if (FarmOptions.FarmNumber[city] >= t.FarmArray[city].length) 
    { 
      FarmOptions.FarmNumber[city]=0;
    }
    
    var knights = getFreeKnight(cityID)
    if(knights.length > 0)
    {
      var kid = knights[0].ID;
    }
    else
    {
      logit("Farm: no free knight in city");
      return;
    }
    
    var interval = 0;
    
    switch(FarmOptions.Interval)
    {
      case "1":interval = 1;break;
      case "2":interval = 2;break;
      case "3":interval = 3;break;
      case "4":interval = 6;break;
      case "5":interval = 12;break;
      case "6":interval = 24;break;
    }
    
    var check = 0;
    
    while (check == 0)
    {
      check = 1;
      
      for (i = 1 ; i <= 12 ; i++)
      {
        if (FarmOptions.Troops[i] > parseInt(Seed.units[cityID]['unt' + i])) 
        {
          check = 0;
        }
      } 
      
      var totalTroops = 0;
      for( i = 1 ; i <= 12 ; i++)
      {
        totalTroops += FarmOptions.Troops[i]; 
      }
      
      if (totalTroops) 
      {
        check = 0;
      }
      
      if (!t.FarmArray[city][FarmOptions.FarmNumber[city]]['enabled']) 
        check = 0;
      
      if (now < (parseInt(t.FarmArray[city][FarmOptions.FarmNumber[city]]['time']) + (3600 * interval))) 
        check = 0;
      
      if (check == 0) 
        FarmOptions.FarmNumber[city]++;
      
      if (FarmOptions.FarmNumber[city] >= t.FarmArray[city].length) 
      {
        FarmOptions.FarmNumber[city] = 0;
        break;
      }
    }
    
    if (check == 0) 
      return;
     
    var xcoord = t.FarmArray[city][FarmOptions.FarmNumber[city]]['x'];
    var ycoord = t.FarmArray[city][FarmOptions.FarmNumber[city]]['y'];
    var uid = t.FarmArray[city][FarmOptions.FarmNumber[city]]['UserId'];
    saveFarmOptions();
    
    if (freeMarchSlots > FarmOptions.RallyClip)
    {    
      t.checkInactives(citynumber,city,FarmOptions.FarmNumber[city],xcoord,ycoord,kid,uid,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12);
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getnextCity: function()
  {
    var t = Tabs.farm;
    
    if (!FarmOptions.Running) return;
    
    if(t.searchRunning) return;
  
    var city = t.city+1;
    
    if (city>Seed.cities.length)
    {
      city=1;
    }
    
    t.city = city;
    t.barbing();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doBarb: function(cityID,counter,number,xcoord,ycoord,kid,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12)
  {
    var t = Tabs.farm;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid=cityID;
    params.type=4;
    params.kid=kid;
    params.xcoord = xcoord;
    params.ycoord = ycoord;
    if (u1>0) params.u1=u1;
    if (u2>0)params.u2=u2;
    if (u3>0)params.u3=u3;
    if (u4>0)params.u4=u4;
    if (u5>0)params.u5=u5;
    if (u6>0)params.u6=u6;
    if (u7>0)params.u7=u7;
    if (u8>0)params.u8=u8;
    if (u9>0)params.u9=u9;
    if (u10>0)params.u10=u10;
    if (u11>0)params.u11=u11;
    if (u12>0)params.u12=u12;
    params.gold =0;
    params.r1=0;
    params.r2=0,
    params.r3=0;
    params.r4=0;
    params.r5=0;

    var _ajaxCall = function()
    {
      var profiler = new CM.Profiler("ResponseTime", "march.php");
      new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
        
        onSuccess: function (transport) 
        {
          profiler.stop();
          var rslt = eval("(" + transport.responseText + ")");
          if (rslt.ok) 
          {
            addOutgoingMarch(params, rslt);
            CheckUpdateSeed(rslt);
            var slots=0;
            
            for(var k in Seed.queue_atkp['city'+cityID]) 
              slots++;
            
            if(Seed.queue_atkp['city'+cityID].toSource() == "[]") 
              slots = 0;
            
            var now = new Date().getTime()/1000.0;
            now = now.toFixed(0);
            t.FarmArray[counter][number]['time'] = now;
            t.FarmArray[counter][number]['attacked']++;
            FarmOptions.FarmMarches.push ({city:counter,cityId:cityID,marchId:rslt.marchId,number:number});
            FarmOptions.FarmNumber[counter]++;
            FarmOptions.Attacks++;
            saveFarmOptions();
            document.getElementById('FarmCheck').innerHTML = "Attacks: " + FarmOptions.Attacks + " - Checks:" + FarmOptions.Checks;
            for (i=0;i<t.helpArray[counter].length;i++)
            {
              for (j=0;j<t.FarmArray[counter].length;j++)
              {
                if (parseInt(t.FarmArray[counter][j]['x']) == parseInt(t.helpArray[counter][i]['x']) && parseInt(t.FarmArray[counter][j]['y']) == parseInt(t.helpArray[counter][i]['y']))
                {
                  t.helpArray[counter][i]['time'] = t.FarmArray[counter][j]['time'];
                  t.helpArray[counter][i]['attacked'] = t.FarmArray[counter][j]['attacked'];
                }    
              }
            }
            GM_setValue('Farms_' + Seed.player['name'] + '_city_' + counter + '_' + getServerId(), JSON2.stringify(t.helpArray[counter]));
          }
          else
          {
            if (rslt.user_action) 
            {
              var user_action = 
              {
                marchWarning: function() 
                {
                  logit('Captcha: [farming] captcha warning');
                  actionLog('Captcha: [farming] captcha warning');
                },
                marchCaptcha: function() 
                {
                  actionLog('Captcha: [farming] triggered captcha');
                  logit('Captcha: [farming] triggered captcha');
                  startCaptcha();
                },
                backOffWaitTime: function() 
                {
                  logit('Captcha: [farming] back off time - ' + rslt.wait_time);
                  actionLog('Captcha: [farming] back off time - ' + rslt.wait_time);
                  params.tt = rslt.tt;
                  setTimeout(_ajaxCall, rslt.wait_time * 1000)
                }
              };
              user_action[rslt.user_action].call();
            }
          }
        },
        
        onFailure: function () 
        {
          profiler.stop();  
        }
      });
    };
    _ajaxCall();

    saveFarmOptions();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  clickedSearch : function ()
  {
    var t = Tabs.farm;
    t.opt.searchType = 0; 
    t.opt.maxDistance = FarmOptions.MaxDistance; 
    t.opt.searchShape = 'circle'; 
    t.mapDat = [];
    t.firstX =  t.opt.startX - t.opt.maxDistance;
    t.lastX = t.opt.startX + t.opt.maxDistance;
    t.firstY =  t.opt.startY - t.opt.maxDistance;
    t.lastY = t.opt.startY + t.opt.maxDistance;
    t.tilesSearched = 0;
    t.tilesFound = 0;
    t.curX = t.firstX;
    t.curY = t.firstY;
    var xxx = t.MapAjax.normalize(t.curX);
    var yyy = t.MapAjax.normalize(t.curY);
    var element = 'pddataFarm'+(t.lookup-1);
    document.getElementById(element).innerHTML = 'Searching at '+ xxx +','+ yyy;
   
    setTimeout (function(){t.MapAjax.request (xxx, yyy, 15, t.mapCallback)}, MAP_DELAY);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  mapCallback : function (left, top, width, rslt)
  {
    var t = Tabs.farm;
    
    if (!t.searchRunning)
      return;
    
    if (!rslt.ok)
    {
      t.stopSearch ('ERROR: '+ rslt.errorMsg);
      return;
    }
    
    map = rslt.data;
    
    for (k in map)
    {
      var dist = distance (t.opt.startX, t.opt.startY, map[k].xCoord, map[k].yCoord); 
      var CityCheck = true;
      var who = "u" + map[k].tileUserId;
      var AllianceName = "";
      
      if (map[k].cityName == null && map[k].misted ==false) 
        CityCheck = false;
      
      if (t.isMyself(map[k].tileUserId)) 
        CityCheck = false;
      
      if (map[k].tileType== 51 && CityCheck) 
      {
        var Diplomacy = "neutral";
        
        for (DipStatus in t.DipArray) 
        {
          var AllianceId = 0;
          
          if (rslt.userInfo[who] != undefined) 
            AllianceId = "a" + rslt.userInfo[who].a;        
          
          for (alliance in Seed.allianceDiplomacies[t.DipArray[DipStatus]]) 
            if (Seed.allianceDiplomacies[t.DipArray[DipStatus]][AllianceId] != undefined) 
              Diplomacy = t.DipArray[DipStatus];
        }
        
        if (rslt.allianceNames[AllianceId] != undefined) 
          AllianceName = rslt.allianceNames[AllianceId];
        
        if (Diplomacy == "neutral" && AllianceName =="") 
          Diplomacy = "unallied";
        t.mapDat.push ({time:0,empty:0,lost:false,enabled:'true',attacked:0,DaysInactive:"?",LastCheck:0,Diplomacy:Diplomacy,UserId:map[k].tileUserId,AllianceName:AllianceName,x:map[k].xCoord,y:map[k].yCoord,dist:dist,level:map[k].tileLevel,PlayerName:rslt.userInfo[who].n,cityName:map[k].cityName,might:rslt.userInfo[who].m,cityNumber:map[k].cityNum});
      }
    }
    t.tilesSearched += (15*15);

    t.curX += 15;
    if (t.curX > t.lastX)
    {
      t.curX = t.firstX;
      t.curY += 15;
      
      if (t.curY > t.lastY)
      {
        var element = 'pdtotalFarm'+(t.lookup-1);
        document.getElementById(element).innerHTML = 'Found: ' + t.mapDat.length;
        var element = 'pddataFarm'+(t.lookup-1);
        document.getElementById(element).innerHTML = "";
        GM_setValue('Farms_' + Seed.player['name'] + '_city_' + t.lookup + '_' + getServerId(), JSON2.stringify(t.mapDat));
        t.searchRunning = false;
        
        for (y=1;y<=8;y++) 
          FarmOptions.FarmNumber[y] = 0;
        
        t.checkFarmData();
        return;
      }
    }
    
    var x = t.MapAjax.normalize(t.curX);
    var y = t.MapAjax.normalize(t.curY);
    var element = 'pddataFarm'+(t.lookup-1);
    document.getElementById(element).innerHTML = 'Searching at '+ x +','+ y;
    setTimeout (function(){t.MapAjax.request (x, y, 15, t.mapCallback)}, MAP_DELAY);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  stopSearch : function (msg)
  {
    var t = Tabs.farm;
    var element = 'pddataFarm'+(t.lookup-1);
    document.getElementById(element).innerHTML = msg;
    t.searchRunning = false;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide : function ()
  {
  
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {
  
  },
}; 

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Throne
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Throne = 
{
  tabOrder : 590,
  tabLabel : 'Throne',
  cont : null,
  curTabBut : null,
  curTabName : null,
  SelId:null,
  log:[],
  SalvageLog:[],
  setRepairTimer:null,
  setActionTimer:null,
  SalvageArray:[],
  SalvageRunning:false,
  LastDeleted:0,
  ItemTypeList: ["Advisor","Banner","Chair","Table","Windows","Trophy","Candelabrum"],
  BoostType: ["Attack","Defense","Life","Speed","Accuracy","Range","Load","MarchSize","MarchSpeed","CombatSkill","IntelligenceSkill","PoliticsSkill","ResourcefulnessSkill","TrainingSpeed","ConstructionSpeed","ResearchSpeed","CraftingSpeed","Upkeep","ResourceProduction","ResourceCap","Storehouse","Morale","ItemDrop"],
  MaxRows:30,
  CompPos:0,
  CardTypes:["ALL","Attack","Defense","Life","Speed","Accuracy","Range","Load","MarchSize","MarchSpeed","CombatSkill","IntelligenceSkill","PoliticsSkill","ResourcefulnessSkill","TrainingSpeed","ConstructionSpeed","ResearchSpeed","CraftingSpeed","Upkeep","ResourceProduction","ResourceCap","Storehouse","Morale","ItemDrop"],
  EquipType: ["ALL","Advisor","Banner","Chair","Table","Trophy","Windows","Candelabrum"],
  Faction: ["ALL","Briton","Fey","Druid"],
  throneBusy: false,
  upgradeStatusFunction: null,
  autoUpgradeStop: false,
  autoUpgradeTries : 0,
  autoUpgradeMessage : 'Waiting for manual request...',
  itemLists : [],
  itemTypes : { chair: 0, table: 1, window: 2, banner: 3, advisor: 4, trophy: 5, candelabrum: 6},
  selectedItems : [],
  panelId: -1,
  panelType: "upgrade",
  panelNextLevel : 2,
  sortEffect: "none",
  sortType: "both",
  sortInactive: true,
  selectedPlayer : 0,
  activeThroneSlot : null,
  activeThroneSlotItems : null,
  customPreset : false,
  itemType: 
  {
    "advisor" : 0,
    "banner"  : 1,
    "chair"   : 2,
    "table"   : 3,
    "window"  : 4,
    "trophy"  : 5,
    "candelabrum" :6,
  },
  changePresetOnSelect : false,
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init : function (div)
  {
    var t = Tabs.Throne;
    t.cont = div;
    
    installHandlerFunctions();
    
    s = GM_getValue ('ThroneHistory_'+getServerId());
    if (s == null || s == undefined)
    {
      s = GM_getValue ('ThroneHistory_'+132, '[]');
    }
    var a = JSON2.parse(s);
    if (matTypeof(a) == 'array') 
      t.log = a;
    
    s = GM_getValue ('ThroneSalvageHistory_'+getServerId());
    if (s == null || s == undefined)
    {
      s = GM_getValue ('ThroneSalvageHistory_'+132, '[]');
    }
    var a = JSON2.parse(s);
    if (matTypeof(a) == 'array') 
      t.SalvageLog = a;

    //populate the throne options if it is not yet there    
    for(itemType in t.ItemTypeList) 
    {
      var item = t.ItemTypeList[itemType];
      
      if (typeof(item) == "string") 
      {
        if(!ThroneOptions.itemAttributes[item]) 
        {
          ThroneOptions.itemAttributes[item] = {};
        }

        for(boostType in t.BoostType) 
        {
          var boost = t.BoostType[boostType];

          if(typeof(boost) == "string") 
          {
            if(!ThroneOptions.itemAttributes[item][boost]) 
            {
              ThroneOptions.itemAttributes[item][boost] = {};
              ThroneOptions.itemAttributes[item][boost].saveValue = 1;
              ThroneOptions.itemAttributes[item][boost].ignoreDebuff = 1;
            }
            
            if(!ThroneOptions.itemAttributes[item][boost].ignoreDebuff) 
            {
              ThroneOptions.itemAttributes[item][boost].ignoreDebuff = 1;
            }
          }
        }
      }
    }

    // switch off the annoying red X and leave the tick for when it works
    var upgradeStatus;
    var newStatus = function (status) 
    {
      if(status == "success") 
      {
        upgradeStatus("success");
      }
    };
    
    upgradeStatus = CM.ThronePanelView.statusAnim;
    t.upgradeStatusFunction = upgradeStatus;
    CM.ThronePanelView.statusAnim = newStatus;
    
    saveThroneOptions();
    
    var main = ""; 

    main += '<div id=pbThroneTabMenu>';
    main += '<TABLE align=center class=pbMainTab><TR align=center>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubOld>Salvage</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubUE >Upg/Enh</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubEQ >Equip</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubCO >Compare</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubUPS>Upg Stats</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubSal>Enh Stats</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubAU>Auto Upgrade</td>';
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubES>Enhanced Salvage</td>';
    if(Options.FullEnable)
    {
      main += '<td class=spacer></td><Td class=notSel id=ptmrchSubOR>Organizer</td>';
    }
    main += '<td class=spacer></td><Td class=notSel id=ptmrchSubTC>Caps</td>';
    main += '</TR></TABLE></div>';
    main += '<HR class=ptThin>';
    main += '<DIV id=ThroneOutput style="margin-top:10px; overflow:auto;"></div>';

    t.cont.innerHTML = main;
    t.Overv = document.getElementById('ThroneOutput');
    
    jQuery("[id^=ptmrchSub]").click( function(event) {e_butSubtab(event);} );
    
    changeSubtab (document.getElementById('ptmrchSubUE'));
    
    function e_butSubtab (evt)
    {            
      changeSubtab (evt.target);   
    }

    function changeSubtab (but)
    {
      if (but == t.curTabBut) 
      {
        return;
      }
      
      if (t.curTabBut)
      {
        t.curTabBut.className='notSel'; 
        t.curTabBut.disabled=false;
      }
      
      t.curTabBut = but;
      but.className='sel'; 
      but.disabled=true;
      t.curTabName = but.id.substr(9);
      t.show ();
    }
    
    t.checkUpgradeInfo(true);
    
    if (ThroneOptions.Active) 
    {
      t.setActionTimer = setInterval(t.doAction, 5 * 1000);
    }
    
    if(Options.thronePresetButtons)
    {
      widget = buildPresetWidget("main");
      populatePresetWidget(widget);
    }
    
    // set the labels on the new salvage tab
    jQuery("a.throne").click( function() 
    {
      // Tabs.throneSalvage.updateTRTab();
      // Tabs.upgrader.updateTRTab();
      //Tabs.upgrader.updateTRSelect();
      jQuery("ul#throneInventoryList > li > div").removeClass('redBorder');
      jQuery("ul#throneInventoryList > li > div").removeClass('yellowBorder');
      jQuery("div#throneMainContainer div#tableContainer").css("left", "290px");

      for (i = 0 ; i < t.SalvageArray.length ; i++) 
      {
        jQuery("div#throneInventoryItem" + t.SalvageArray[i]).addClass('redBorder');
      }
      
      for (i = 0 ; i < ThroneOptions.Items.length ; i++)
      {
        jQuery("div#throneInventoryItem" + ThroneOptions.Items[i].id).addClass('yellowBorder');
      }
      
      for (i = 0 ; i < ThroneOptions.protectList.length ; i++)
      {
        jQuery("div#throneInventoryItem" + ThroneOptions.protectList[i]).addClass('greenBorder');
      }

      jQuery("ul#throneInventoryList").css('height', '520px');
      jQuery("div#throneInventoryContainer").css('height', '520px');
      
      // update the other presets buttons when clicked
      jQuery('ul#throneStatList li.active, ul#throneStatList li.selected').click(function () 
      {
        var s = jQuery(this).attr('id').split('throneInventoryPreset')[1];
        setPresetWidget(+s);
      });
    });

    
    setInterval(t.salvageCheck, Options.salvageInterval * 1000);
    setInterval(t.paintAutoUpgradeData, 2 * 1000);
    setInterval(t.paintStones, 2 * 1000);
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  Compare :function ()
  {
    var t = Tabs.Throne;  
    var amount = 0;
    var AdvisorCount =0;
    var BannerCount = 0;
    var ChairCount = 0;
    var TableCount = 0;
    var TrophyCount = 0;
    var WindowCount = 0;
    var CandelabrumCount = 0;
    var counter = 0;
    ActiveItems = parseInt(Seed.throne.rowNum) * 5;

    for (k in unsafeWindow.kocThroneItems)
    {
      counter++;
      
      if (counter > ActiveItems) 
        break;
        
      z = unsafeWindow.kocThroneItems[k];
      if (z.type=="advisor") AdvisorCount++;
      if (z.type=="banner") BannerCount++;
      if (z.type=="chair") ChairCount++;
      if (z.type=="trophy") TrophyCount++;
      if (z.type=="table") TableCount++;
      if (z.type=="window") WindowCount++;
      if (z.type=="candelabrum") CandelabrumCount++;
    } 


    try 
    {   
      var m = '<DIV id=pbTowrtDivF class=pbStat>Compare Throne Items</div><br><TABLE id=pbCompareStats width=100% height=0% class=pbTab>';

      m+='<TD>Advisor: ' + AdvisorCount + '</td><TD>Banner: ' + BannerCount+ '</td><TD>Throne :' + ChairCount+ '</td><TD>Table: '+ TableCount+'</td><TD>Trophy: ' + TrophyCount + '</td><TD>Window: ' + WindowCount + '</td><TD>Candelabrum: ' + CandelabrumCount + '</td></table><br>';

      m += '<DIV id=pbThroneMain class=pbStat>Compare Throne Items</div><br>';
      m += '<TABLE id=pbCompareStats width=100% height=0% class=pbTab>';
      m += '<tr><td>Card Type: <SELECT id=type type=list></select></td><TD>Card Family: <SELECT id=family type=list></select></td><TD>Effect: <SELECT id=effect type=list></select></td></tr>';
      m += '<tr><td>Keyword: <INPUT type=text id=keyword size=10></td></tr>';
      m += '</table>';

      m+='<br><div style="height:500px; max-height:800px; overflow-y:scroll"><TABLE id=pbbarbingfunctions width=100% height=0% class=pbTab><TR>';

      for (i = 1 ; i <= ActiveItems ; i++)
      {
        m+='<TD><DIV id=DIV'+ i +'></div></td>';
        if (i % 3 == 0) 
          m+='</tr><TR></tr><TR>';
      }

      m+="</tr></table></div>"

      t.Overv.innerHTML = m;

      document.getElementById("type").options.length=0;
      
      for (k in t.EquipType)
      {
        var y = t.EquipType[k];
        
        if (typeof(y) == "string") 
        {
          if (y == "Windows") 
            y = "Window";
          what = y.toLowerCase();
          
          if (y == "Chair") 
            y = "Throne";
          
          var o = document.createElement("option");     
          o.text = y;
          o.value = what;
          document.getElementById("type").options.add(o);
        }   
      } 
      
      document.getElementById("family").options.length=0;
      
      for (k in t.CardTypes)
      {
        var y = t.CardTypes[k];
        
        if (typeof(y) == "string") 
        {
          var o = document.createElement("option");     
          o.text = y;
          o.value = y;
          document.getElementById("family").options.add(o);
        }   
      } 
      
      document.getElementById("effect").options.length=0;
      var o = document.createElement("option");     
      o.text = "ALL";
      o.value = "ALL";
      
      document.getElementById("effect").options.add(o);
      
      for (k in unsafeWindow.cm.thronestats.effects)
      {
        var y = unsafeWindow.cm.thronestats.effects[k][1];
        if (typeof(y) == "string") 
        {
          var o = document.createElement("option");     
          o.text = unsafeWindow.cm.thronestats.effects[k][1];
          o.value = k;
          document.getElementById("effect").options.add(o);
        }   
      } 

      document.getElementById("type").addEventListener ('change', t.FillEquipCheckboxes,false);
      document.getElementById("family").addEventListener ('change', t.FillEquipCheckboxes,false);
      document.getElementById("effect").addEventListener ('change', t.FillEquipCheckboxes,false);
      document.getElementById("keyword").addEventListener ('change', t.FillEquipCheckboxes,false);
      document.getElementById('keyword').addEventListener('keyup', t.FillEquipCheckboxes, false)
          

      t.FillEquipCheckboxes();
    } 
    catch (e) 
    {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  FillEquipCheckboxes: function()
  {
    var t = Tabs.Throne;
    var familyCheck=false;
    var typeCheck=false;
    var effectCheck=false;
    var keywordCheck=false;  
    
    ActiveItems = parseInt(Seed.throne.rowNum) * 5;
    
    for(i=1;i<=ActiveItems;i++) 
      document.getElementById("DIV"+i).innerHTML="";
    
    counter = 0;
    t.CompPos=0;
    
    for (k in unsafeWindow.kocThroneItems)
    {
      counter++;
      
      if (counter > ActiveItems) 
        break;
      
      z = unsafeWindow.kocThroneItems[k];
      familyCheck=false;
      typeCheck=false;
      effectCheck=false;
      keywordCheck=false;
      y = z.effects;
      
      if (z.type==document.getElementById("type").value || "all" == document.getElementById("type").value) 
        typeCheck=true;

      for (i = 1 ; i <= 5 ; i++)
      {
        effect = unsafeWindow.cm.thronestats['effects'][y['slot'+i].id][2];
        
        if (effect == document.getElementById("family").value || "ALL" == document.getElementById("family").value) 
          familyCheck = true;
        
        if (y['slot'+i].id == document.getElementById("effect").value || "ALL" == document.getElementById("effect").value) 
          effectCheck = true;
        
        var str = String(unsafeWindow.cm.thronestats['effects'][y['slot'+i].id][1]);
        
        if (str.search(new RegExp(String(document.getElementById("keyword").value), "i")) != -1 || document.getElementById("keyword").value=="") 
          keywordCheck=true;
      }

      if (typeCheck && familyCheck && effectCheck && keywordCheck)
      {
        t.CompPos++;
        t.paintEquipInfo(z.id, t.CompPos);
      }
    } 
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintEquipInfo : function (z,what)
  {
    var t = Tabs.Throne;
    var m="";
    var color = "black";
    
    if (typeof(unsafeWindow.kocThroneItems[z]) == 'object') 
      var y = unsafeWindow.kocThroneItems[z];
    else 
      return;
    
    var id =0;
    var tier=0;
    var Current=0;

    var icon = 'http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/throne/icons/30/' + y.faction + '/' + y.faction + '_'+ y.type +'_normal_1_'+ y.quality+'.png';
    
    if (y.isEquipped) 
      m = '<TABLE width=80% height=0% align="center" class=ThroneEQ style="background: transparent url('+icon +') bottom right no-repeat; background-color:#FFFFE3;">';
    else 
      m = '<TABLE width=80% height=0% align="center" class=Throne style="background: transparent url('+icon +') bottom right no-repeat; background-color:#FFFFE3;">';

    switch(parseInt(y["quality"]))
    {
      case 1:
        color="grey";
        break;
      case 2:
        color="white";
        break;
      case 3:
        color="green";
        break;
      case 4:
        color="blue";
        break;
      case 5:
        color="purple";
        break;
      default:
        break;
    }

    m+='<TR><TD style="background-color:#D5C795"><FONT color='+ color +'><B>' + y.name + '</b></font></td>';
    m+= '<TD><A onclick="Savlage('+ y.id +')"><img src=""/></td></tr>';
    
    for (i = 1 ; i <= 5 ; i++) 
    {
      id = y["effects"]["slot"+i]["id"];
      tier = parseInt(y["effects"]["slot"+i]["tier"]);
      level = y["level"];
      p = unsafeWindow.cm.thronestats.tiers[id][tier];
      Current = p.base + ((level * level + level) * p.growth * 0.5);
      var quality = parseInt(y["quality"]);
      
      if (i <= quality) 
        m+='<TR><TD><FONT color=black>' + Current.toFixed(2) + "% " + unsafeWindow.cm.thronestats["effects"][id]["1"] + '</font></td></tr>';
      else 
        m+='<TR><TD><FONT color=grey>' + Current.toFixed(2) + "% " + unsafeWindow.cm.thronestats["effects"][id]["1"] + '</font></td></tr>';
    }
    
    m += "</table>"
    
    document.getElementById('DIV'+what).innerHTML = m;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  Caps : function ()
  {
    var t =Tabs.Throne;
    m =  '<DIV class=ptstat><b>Throne Room Caps</b></div><TABLE border=2px align=center>';
    m += '<TR><TD width="150px"><B>Boost Name</b></td><TD width="50px"><B>Max</b></td><TD><B>Min</b></td><TD style="border:0;width:50px"></td><TD width="150px"><B>Boost Name</b></td><TD width="50px"><B>Max</b></td><TD width="50px"><B>Min</b></td></tr><TR>';
    var counter =0;
    
    for (k in unsafeWindow.cm.thronestats.boosts)
    {
      counter++
      var boost = unsafeWindow.cm.thronestats.boosts[k]
      m += '<TD>'+ boost.BoostName + '</td><TD>'+ boost.Max +'<SPAN id=maxPerc_'+k+'></div></td><TD>' + boost.Min + '<SPAN id=minPerc_'+k+'></div>';

      if (counter % 2 == 0)
      {
        m += '<TR>';
      }
      else 
      {
        m += '</td><TD style="border:0">';
      }
    }
    
    t.Overv.innerHTML = m;
    
    for (k in unsafeWindow.cm.thronestats.boosts)
    {
      var boost = unsafeWindow.cm.thronestats.boosts[k]
      
      if (boost.CapType == "percent")
      {
        document.getElementById('maxPerc_'+k).innerHTML = '%'
        
        if (boost.Min != "none")
        {
          document.getElementById('minPerc_'+k).innerHTML = '%'
        }
      }
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  Salvage : function ()
  { 
    var t = Tabs.Throne; 
    try 
    {      
      m = '<DIV id=pbTowrtDivF class=pbStat>AUTOMATED SALVAGE FUNCTION</div><TABLE id=pbbarbingfunctions width=100% class=pbTab>';
      m+='<TR><TD><INPUT type=submit id=pbsalvage_run value="Auto Salvage = '+(Options.ThroneDeleteItems?'ON':'OFF')+'" /></td><TD><INPUT id=ShowSalvageHistory type=submit value="History"></td><TD>Keep items with more than <INPUT type=text id=pbthrone_keep size=3 value="'+ThroneOptions.thronekeep+'" /> stats checked.</td></tr>';
      m+='<TR><TD>Keep above: ' + htmlSelector({0:'ALL', 1:translate('Common'), 2:translate('Uncommon'), 3:translate('Rare'), 4:translate('Epic'), 5:translate('Wonderous')},ThroneOptions.SalvageQuality,'id=Quality')+'</td>';
      m+='<TD>Keep first <INPUT type=text id=saveXitems size=2 maxlength=2 value='+ ThroneOptions.saveXitems +'> items.</td><TD><FONT color=red>Check boxes for items you want to <b>KEEP</b>.</font></td></table>';
      
      m+='<TABLE id=pbbarbingfunctions width=60% class=pbTab><TR><TD><B>Combat:</b></td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Attack type=checkbox '+ (ThroneOptions.Salvage.Attack?'CHECKED ':'') +'/>&nbsp;Attack</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Defense type=checkbox '+ (ThroneOptions.Salvage.Defense?'CHECKED ':'') +'/>&nbsp;Defense</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Life type=checkbox '+ (ThroneOptions.Salvage.Life?'CHECKED ':'') +'/>&nbsp;Life</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Speed type=checkbox '+ (ThroneOptions.Salvage.Speed?'CHECKED ':'') +'/>&nbsp;Speed</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Accuracy type=checkbox '+ (ThroneOptions.Salvage.Accuracy?'CHECKED ':'') +'/>&nbsp;Accuracy</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Range type=checkbox '+ (ThroneOptions.Salvage.Range?'CHECKED ':'') +'/>&nbsp;Range</td></tr>';
      m+='<TR></tr><TR><TD><B>March:</b></td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Load type=checkbox '+ (ThroneOptions.Salvage.Load?'CHECKED ':'') +'/>&nbsp;Load</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=MarchSize type=checkbox '+ (ThroneOptions.Salvage.MarchSize?'CHECKED ':'') +'/>&nbsp;March Size</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=MarchSpeed type=checkbox '+ (ThroneOptions.Salvage.MarchSpeed?'CHECKED ':'') +'/>&nbsp;March Speed</td></tr>';
      m+='<TR></tr><TR><TD><B>Skills:</b></td></tr>';
      m+='<TR><TD></td><TD><INPUT id=CombatSkill type=checkbox '+ (ThroneOptions.Salvage.CombatSkill?'CHECKED ':'') +'/>&nbsp;Combat Skill</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=IntelligenceSkill type=checkbox '+ (ThroneOptions.Salvage.IntelligenceSkill?'CHECKED ':'') +'/>&nbsp;Intelligence Skill</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=PoliticsSkill type=checkbox '+ (ThroneOptions.Salvage.PoliticsSkill?'CHECKED ':'') +'/>&nbsp;Politics Skill</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=ResourcefulnessSkill type=checkbox '+ (ThroneOptions.Salvage.ResourcefulnessSkill?'CHECKED ':'') +'/>&nbsp;Resourcefulness Skill</td></tr>';
      m+='<TR></tr><TR><TD><B>Speed:</b></td></tr>';
      m+='<TR><TD></td><TD><INPUT id=TrainingSpeed type=checkbox '+ (ThroneOptions.Salvage.TrainingSpeed?'CHECKED ':'') +'/>&nbsp;Training Speed</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=ConstructionSpeed type=checkbox '+ (ThroneOptions.Salvage.ConstructionSpeed?'CHECKED ':'') +'/>&nbsp;Construction Speed</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=ResearchSpeed type=checkbox '+ (ThroneOptions.Salvage.ResearchSpeed?'CHECKED ':'') +'/>&nbsp;Research Speed</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=CraftingSpeed type=checkbox '+ (ThroneOptions.Salvage.CraftingSpeed?'CHECKED ':'') +'/>&nbsp;Crafting Speed</td></tr>';
      m+='<TR></tr><TR><TD><B>Recources:</b></td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Upkeep type=checkbox '+ (ThroneOptions.Salvage.Upkeep?'CHECKED ':'') +'/>&nbsp;Upkeep</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=ResourceProduction type=checkbox '+ (ThroneOptions.Salvage.ResourceProduction?'CHECKED ':'') +'/>&nbsp;Resource Production</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=ResourceCap type=checkbox '+ (ThroneOptions.Salvage.ResourceCap?'CHECKED ':'') +'/>&nbsp;Resource Cap</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Storehouse type=checkbox '+ (ThroneOptions.Salvage.Storehouse?'CHECKED ':'') +'/>&nbsp;Storehouse</td></tr>';
      m+='<TR></tr><TR><TD><B>Varia:</b></td></tr>';
      m+='<TR><TD></td><TD><INPUT id=Morale type=checkbox '+ (ThroneOptions.Salvage.Morale?'CHECKED ':'') +'/>&nbsp;Morale</td></tr>';
      m+='<TR><TD></td><TD><INPUT id=ItemDrop type=checkbox '+ (ThroneOptions.Salvage.ItemDrop?'CHECKED ':'') +'/>&nbsp;ItemDrop</td></tr></table>';
      
      t.Overv.innerHTML = m;
      
      $("pbsalvage_run").addEventListener('click', function(e){
        if(Options.ThroneDeleteItems) {
          e.target.value = "Auto Salvage = OFF";
          Options.ThroneDeleteItems = false;
          saveOptions();
        } else {
          e.target.value = "Auto Salvage = ON";
          Options.ThroneDeleteItems = true;
          saveOptions();
        }
      },false);
      
      document.getElementById('Attack').addEventListener ('change', function(){ThroneOptions.Salvage.Attack = document.getElementById('Attack').checked;saveThroneOptions();},false);
      document.getElementById('Defense').addEventListener ('change', function(){ThroneOptions.Salvage.Defense = document.getElementById('Defense').checked;saveThroneOptions();},false);
      document.getElementById('Life').addEventListener ('change', function(){ThroneOptions.Salvage.Life = document.getElementById('Life').checked;saveThroneOptions();},false);
      document.getElementById('Speed').addEventListener ('change', function(){ThroneOptions.Salvage.Speed = document.getElementById('Speed').checked;saveThroneOptions();},false);
      document.getElementById('Accuracy').addEventListener ('change', function(){ThroneOptions.Salvage.Accuracy = document.getElementById('Accuracy').checked;saveThroneOptions();},false);
      document.getElementById('Range').addEventListener ('change', function(){ThroneOptions.Salvage.Range = document.getElementById('Range').checked;saveThroneOptions();},false);
      document.getElementById('Load').addEventListener ('change', function(){ThroneOptions.Salvage.Load = document.getElementById('Load').checked;saveThroneOptions();},false);
      document.getElementById('MarchSize').addEventListener ('change', function(){ThroneOptions.Salvage.MarchSize = document.getElementById('MarchSize').checked;saveThroneOptions();},false);
      document.getElementById('MarchSpeed').addEventListener ('change', function(){ThroneOptions.Salvage.MarchSpeed = document.getElementById('MarchSpeed').checked;saveThroneOptions();},false);
      document.getElementById('CombatSkill').addEventListener ('change', function(){ThroneOptions.Salvage.CombatSkill = document.getElementById('CombatSkill').checked;saveThroneOptions();},false);
      document.getElementById('IntelligenceSkill').addEventListener ('change', function(){ThroneOptions.Salvage.IntelligenceSkill = document.getElementById('IntelligenceSkill').checked;saveThroneOptions();},false);
      document.getElementById('PoliticsSkill').addEventListener ('change', function(){ThroneOptions.Salvage.PoliticsSkill = document.getElementById('PoliticsSkill').checked;saveThroneOptions();},false);
      document.getElementById('ResourcefulnessSkill').addEventListener ('change', function(){ThroneOptions.Salvage.ResourcefulnessSkill = document.getElementById('ResourcefulnessSkill').checked;saveThroneOptions();},false);
      document.getElementById('TrainingSpeed').addEventListener ('change', function(){ThroneOptions.Salvage.TrainingSpeed = document.getElementById('TrainingSpeed').checked;saveThroneOptions();},false);
      document.getElementById('ConstructionSpeed').addEventListener ('change', function(){ThroneOptions.Salvage.ConstructionSpeed = document.getElementById('ConstructionSpeed').checked;saveThroneOptions();},false);
      document.getElementById('ResearchSpeed').addEventListener ('change', function(){ThroneOptions.Salvage.ResearchSpeed = document.getElementById('ResearchSpeed').checked;saveThroneOptions();},false);
      document.getElementById('CraftingSpeed').addEventListener ('change', function(){ThroneOptions.Salvage.CraftingSpeed = document.getElementById('CraftingSpeed').checked;saveThroneOptions();},false);
      document.getElementById('Upkeep').addEventListener ('change', function(){ThroneOptions.Salvage.Upkeep = document.getElementById('Upkeep').checked;saveThroneOptions();},false);
      document.getElementById('ResourceProduction').addEventListener ('change', function(){ThroneOptions.Salvage.ResourceProduction = document.getElementById('ResourceProduction').checked;saveThroneOptions();},false);
      document.getElementById('ResourceCap').addEventListener ('change', function(){ThroneOptions.Salvage.ResourceCap = document.getElementById('ResourceCap').checked;saveThroneOptions();},false);
      document.getElementById('Storehouse').addEventListener ('change', function(){ThroneOptions.Salvage.Storehouse = document.getElementById('Storehouse').checked;saveThroneOptions();},false);
      document.getElementById('Morale').addEventListener ('change', function(){ThroneOptions.Salvage.Morale = document.getElementById('Morale').checked;saveThroneOptions();},false);
      document.getElementById('ItemDrop').addEventListener ('change', function(){ThroneOptions.Salvage.ItemDrop = document.getElementById('ItemDrop').checked;saveThroneOptions();},false);
      document.getElementById('pbthrone_keep').addEventListener ('change', function(){ThroneOptions.thronekeep = parseInt(document.getElementById('pbthrone_keep').value);saveThroneOptions();},false);

      document.getElementById('Quality').addEventListener  ('change', function(){ThroneOptions.SalvageQuality = this.value;saveThroneOptions();},false);
      document.getElementById('saveXitems').addEventListener('change', function(){ThroneOptions.saveXitems = document.getElementById('saveXitems').value;saveThroneOptions();} , false);
      document.getElementById('ShowSalvageHistory').addEventListener('click', function(){t.PaintSalvageHistory()} , false);

      
    } catch (e) {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  upgradeStatsTab : function ()
  {
    var t = Tabs.Throne;
    var m = '';
    m += '<DIV id= trStatsTabDiv2 align=left style="margin-top:5px; margin-bottom:5px; margin-left: 5px;">';
    m += '<TABLE class=trStatTab align=center cellspacing=0>';

    m += '<TR valign=top align=center><TH colspan=12>Upgrading Numbers  (successes/failures)</TH></TR>';

    var qstrings = new Array(uW.g_js_strings.throneRoom.simple,  uW.g_js_strings.throneRoom.common, uW.g_js_strings.throneRoom.uncommon,
            uW.g_js_strings.throneRoom.rare,    uW.g_js_strings.throneRoom.epic,   uW.g_js_strings.throneRoom.wondrous);


    m += '<TR valign=top align=center><th></th>';

    for (l = 0 ; l < 10 ; l++)
    {
        m += "<th style='font-weight: bold;' class='td" + (l % 2) +"'  >";
        m += "+" +(l+1) + "</th>";
    }
    m += '</TR>';
    var st = [0,0,0,0,0,0,0,0,0,0,0];
    var ft = [0,0,0,0,0,0,0,0,0,0,0];

    for( q =0; q <=5; q++)
    {
        m += '<TR valign=top align=center><th>' + qstrings[q] + '</th>';
        for (l=0; l<10; l++)
        {
            var success = upgradeStats.upgradeSuccess[q][l];
            var failure = upgradeStats.upgradeFailure[q][l];
            
            if (success === undefined) {
              success = 0;
            }
            
            if (failure === undefined) {
              failure = 0;
            }
            
            st[l] += success;
            ft[l] += failure;

            var percentage = ((success * 100) / (success + failure));

            if(isNaN(percentage)) {
              percentage = 0;
            }
            
            m += "<td class='td" + (l%2) +"'  >";
            m += success + " / " + failure + "<br>(" + percentage.toFixed(2) + "%)";
            m += "</td>";
        }
        m += '</TR>';
    }

    m += '<TR valign=top align=center><th> Totals: </th>';
    for( l =0; l<10; l++)
    {
        m += "<td style='font-weight: bold;' class='td" + (l%2) +"'  >";
        m += st[l] + " / " + ft[l];
        m += "</td>";
    }
    m += '</TR>';

    m += '<TR valign=top align=center><th> Percents: </th>';
    for( l =0; l <10; l++)
    {
        m += "<td style='font-weight: bold;' class='td" + (l%2) +"'  >";
        if ( (st[l] + ft[l]) == 0 )
            m += "--";
        else
        {
            var p = (100* st[l] / (st[l] + ft[l]));
            m += p.toFixed(2) + "%";
        }
        m += "</td>";
    }
    m += '</TR>';

    m += '</TABLE></DIV>';

    m += "<div id='trStats2'></div>";
    m += '</div>';
    t.Overv.innerHTML = m;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  enhanceStatsTab :function()   
  {
    var t = Tabs.Throne;
    var m = '<DIV class=trstat style="margin-top:5px; margin-bottom:5px;">';
    m += '<DIV id= trStatsTabDiv align=left style="margin-top:5px; margin-bottom:5px; margin-left: 5px;">';
    m += '<TABLE class=trStatTab align=center cellspacing=0>';

    m += '<TR valign=top align=center><TH colspan=6>Enhancing Numbers  (successes/failures)</TH></TR>';

    var qstrings = new Array(uW.g_js_strings.throneRoom.simple,  uW.g_js_strings.throneRoom.common, uW.g_js_strings.throneRoom.uncommon,
            uW.g_js_strings.throneRoom.rare,    uW.g_js_strings.throneRoom.epic,   uW.g_js_strings.throneRoom.wondrous);


    m += '<TR valign=top align=center><th></th>';
    for( q =1; q <=5; q++)
    {
        m += "<td style='font-weight: bold;' class='td" + (q%2+1) +"'  >";
        m += qstrings[q];
        m += '</td>';
    }

    m += '</tr>';

    var st = [0,0,0,0,0];
    var ft = [0,0,0,0,0];

    for (l=0; l<=10; l++)
    {
        m += '<TR valign=top align=center>';
        m += "<th>";
        if (l !=0) m += "+";
        m+=  l + '</th>';
        for( q = 0; q < 5; q++)
        {
            var success = upgradeStats.enhanceSuccess[q][l];
            var failure = upgradeStats.enhanceFailure[q][l];

            if (success === undefined) {
              success = 0;
            }
            
            if (failure === undefined) {
              failure = 0;
            }
            
            st[q] += success;
            ft[q] += failure;

            var percentage = ((success * 100) / (success + failure));

            if(isNaN(percentage)) {
              percentage = 0;
            }
            
            m += "<td class='td" + (q % 2) +"'  >";
            m += success + " / " + failure + "<br>(" + percentage.toFixed(2) + "%)";
            m += "</td>";
        }
        m += '</TR>';
    }

    m += '<TR valign=top align=center><th> Totals: </th>';
    for( q = 0; q < 5; q++)
    {
        m += "<td style='font-weight: bold;' class='td" + (q % 2) +"'  >";
        m += st[q] + " / " + ft[q];
        m += "</td>";
    }
    m += '</TR>';

    m += '<TR valign=top align=center><th> Percents: </th>';
    for( q = 0; q < 5; q++)
    {
        m += "<td style='font-weight: bold;' class='td" + (q % 2) +"'  >";
        if ( (st[q] + ft[q]) == 0 )
            m += "--";
        else
        {
            var p = (100 * st[q] / (st[q] + ft[q]));
            m += p.toFixed(2) + "%";
        }
        m += "</td>";
    }
    m += '</TR>';

    m += '</TABLE></DIV>';

    m += "<div id=''></div>";
    m += '</div>';

    t.Overv.innerHTML = m;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  SalvageTab : function ()
  { 
    var t = Tabs.Throne; 
    var qualitySelector = {0:'----', 1:'Any', 4:'R', 8:'E', 12:"R,E", 16:'W', 20:'R,W', 24:'E,W', 25:'E,W+1', 28:'R,E,W', 29:"4+", 31:"5"};
    var citySelector = {};
    
    try {
      citySelector[0] = "-----";
      for (var i = 0; i < Cities.cities.length; i++) 
      {
        citySelector[Cities.cities[i].id] = Cities.cities[i].name;
      }
      
      m = '<div style="height:640px;">';
      m += '<DIV id=pbSalvageOptionsHeading class=pbStat>Salvage Options [Auto Salvage : <span id=pbSalvageOptionsState>' + (Options.ThroneDeleteItems ? 'ON' : 'OFF') + '</span>]<span id=pbSalvageOptionsIcon class=down></span></div>';
      m += '<div id=pbSalvageOptions>';
      m += '<TABLE class=ptTab>';
      m += '<TR><TD colspan="2"><b>'+translate("Throne Room Auto Salvage")+':</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT id=DisplaySalvageHistory type=submit value="History"></td></tr>';
      m += '<TR><TD><INPUT id=deletethrone type=checkbox '+ (Options.ThroneDeleteItems?'CHECKED ':'') +'/></td><TD> '+translate("Enable Auto Salvage")+' ['+translate("Bot Deleted")+': &nbsp;' + Options.throneDeletedNum + '&nbsp; '+translate("Items")+']</td></tr>';
      m += '<TR><TD>&nbsp;&nbsp;&nbsp-</td><td>'+translate("Save the first")+': <INPUT id=throneSaveNum type=text size=2 maxlength=3 \> '+translate("items")+'</td></tr>';
      m += '<TR><TD>&nbsp;&nbsp;&nbsp-</td><td>'+translate("Salvage Interval")+': <INPUT id=pbSalvageInterval type=text size=3 maxlength=3 \> '+translate("seconds")+'</td></tr>';
      m += '<TR><TD><INPUT id=ThroneSpaceWarning type=checkbox '+ (Options.ThroneSpaceWarning?'CHECKED ':'') +'/></td><td>'+translate("Warn if less than")+': <INPUT id=ThroneSpaceCount type=text size=2 maxlength=3 \> '+translate("empty throne item spaces")+'</td></tr>';
      m += '<TR><TD><INPUT id=ignoreWildBoosts type=checkbox '+ (ThroneOptions.ignoreWildBoosts?'CHECKED ':'') +'/></td><td>'+translate("Ignore non PvP type boosts (e.g. barb camps, wilds)")+'</td></tr>';
      m += '<TR><TD><INPUT id=ignoreWallBoosts type=checkbox '+ (ThroneOptions.ignoreWallBoosts?'CHECKED ':'') +'/></td><td>'+translate("Ignore wall type boosts (e.g. xbows, wall, spikes)")+'</td></tr>';
      m += '<TR><TD><INPUT id=protectItems type=checkbox '+ (SessionOptions.protectItems?'CHECKED ':'') +'/></td><td>'+translate("Protect upgraded items from salvage")+'</td></tr>';
      m += '<TR><TD><INPUT id=pbMassSalvage type=checkbox '+ (ThroneOptions.enableMassSalvage?'CHECKED ':'') +'/></td><td>'+translate("Enable mass salvage within throne room")+'</td></tr>';
      m += '<TR><TD><INPUT id=pbSalvageToMainCity type=checkbox '+ (ThroneOptions.salvageToMainCity?'CHECKED ':'') +'/></td><td>'+translate("Salvage to main city until full")+'</td></tr>';
      m += '<TR><TD>&nbsp;&nbsp;&nbsp-</td><td>'+translate("Main City for Salvage")+'&nbsp;&nbsp;'+ htmlSelector(citySelector, ThroneOptions.salvageMainCity, 'id=pbSalvageMainCity' ) + '</td></tr>';
      m += '<TR><TD>&nbsp;&nbsp;&nbsp-</td><td>'+translate("Minimum amount for other cities")+'&nbsp;&nbsp;<INPUT id=pbSalvageToMainLowLimit type=text size=7 maxlength=7 value=' + parseIntWithDefault(ThroneOptions.salvageToMainLowLimit, 20000) + '\></td></tr>';
      m += '</table>';
      m += '</div>';
      m += '<br>';
      
      m += '<DIV id=pbSalvageOptionsHeading class=pbStat>Configure Boosts to Keep</div>';
      m += '<div>';
      m += '<TABLE class=ptTab style="margin-left:auto; margin-right:auto;">';
      m += '<tr><th>Booost Type</th>';

      for(itemType in t.ItemTypeList) {
        var item = t.ItemTypeList[itemType];
        if (typeof(item) == "string") {
          m += '<th>'+ item +'</th>'
        }
      }
      m += '</tr>';
      
      for(boostType in t.BoostType) 
      {
        var boost = t.BoostType[boostType];
        
        if(typeof(boost) == "string") 
        {
          m+= '<tr><th>' + boost + '</th>';
          
          for(itemType in t.ItemTypeList) 
          {
            var item = t.ItemTypeList[itemType];
            if (typeof(item) == "string") 
            {
              m+= '<td>'+ htmlSelector(qualitySelector, ThroneOptions.itemAttributes[item][boost].saveRange, 'id=selectMode_' + item + '_' + boost) + '</td>';
                // + '<INPUT id=selectIgnoreDebuff_' + item + '_' + boost + ' type=checkbox '+ (!ThroneOptions.itemAttributes[item][boost].ignoreDebuff?'CHECKED ':'') +'/>Ignore Debuffs</td>'
            }
          }
          
          m+= '</tr>';
        }
      }

      m += '</table>';
      m += '</div>';
      
      m += '<hr/>';
      
      m += '<TABLE class=ptTab>';
      m += '<Caption>Selection Key:</caption>';
      m += '<tr><th>Option</th><th>Meaning</th></tr>';
      m += '<tr><td>---</td><td>Dont save items with this boost</td></tr>';
      m += '<tr><td>Any</td><td>Save an item if this boost appears in any line</td></tr>';
      m += '<tr><td>R</td><td>Save an item if this boost appears in the Rare line or above</td></tr>';
      m += '<tr><td>E</td><td>Save an item if this boost appears in the Epic OR Wonderous line</td></tr>';
      m += '<tr><td>R,E</td><td>Save an item if this boost appears in the Epic AND Wonderous line</td></tr>';
      m += '<tr><td>W</td><td>Save an item if this boost appears in the Wonderous line</td></tr>';
      m += '<tr><td>R,W</td><td>Save an item if this boost appears in the Rare OR Epic line and also the Wonderous line</td></tr>';
      m += '<tr><td>E,W</td><td>Save an item if this boost appears in the Epic AND Wonderous line</td></tr>';
      m += '<tr><td>E,W+1</td><td>Save an item if this boost appears in the Epic line, Wonderous line and one other line</td></tr>';
      m += '<tr><td>R,E,W</td><td>Save an item if this boost appears in ALL of the Rare, Epic and Wonderous lines</td></tr>';
      m += '<tr><td>4+</td><td>Save an item if there are 4+ of the same boost. Must include Rare, Epic and Wonderous lines</td></tr>';
      m += '<tr><td>5</td><td>Save an item if all 5 lines are the same boost</td></tr>';
      m += '</table>';
      m += '<p>An item will be saved if any rule defined matches against the item. Other salvage rules may also prevent an item from being deleted (e.g. TR position of item)</p>';
      m += '</div>';
      
      t.Overv.innerHTML = m;

      jQuery('#pbSalvageOptions').hide();
      
      jQuery('#pbSalvageOptionsHeading').click(function()
      {
        jQuery('#pbSalvageOptions').slideToggle('fast');
        if(jQuery('#pbSalvageOptionsIcon').hasClass('up'))
        {
          jQuery('#pbSalvageOptionsIcon').removeClass('up');
          jQuery('#pbSalvageOptionsIcon').addClass('down');
        }
        else
        {
          jQuery('#pbSalvageOptionsIcon').removeClass('down');
          jQuery('#pbSalvageOptionsIcon').addClass('up');
        }
      });

      for(boostType in t.BoostType) {
        var boost = t.BoostType[boostType];
        if(typeof(boost) == "string") {
          for(itemType in t.ItemTypeList) {
            var item = t.ItemTypeList[itemType];
            if (typeof(item) == "string") {
              t.changeTrSaveOpt('selectMode_' + item + '_' + boost, item, boost);
              // t.togTrSaveOpt('selectIgnoreDebuff_' + item + '_' + boost,item,boost);
            }
          }
        }
      }
      
      document.getElementById('ignoreWildBoosts').addEventListener ('change', function(){
        ThroneOptions.ignoreWildBoosts = this.checked;
        saveThroneOptions();
      },false);
      document.getElementById('ignoreWallBoosts').addEventListener ('change', function(){
        ThroneOptions.ignoreWallBoosts = this.checked;
        saveThroneOptions();
      },false);
      document.getElementById('protectItems').addEventListener ('change', function(){
        SessionOptions.protectItems = this.checked;
      },false);
      document.getElementById('pbMassSalvage').addEventListener ('change', function(){
        ThroneOptions.enableMassSalvage = this.checked;
        saveThroneOptions();
      },false);

      document.getElementById('DisplaySalvageHistory').addEventListener('click', function(){t.PaintSalvageHistory()} , false);

      jQuery("#deletethrone").change(function()
      {
        Options.ThroneDeleteItems = this.checked;
        jQuery('#pbSalvageOptionsState').text(Options.ThroneDeleteItems ? 'ON' : 'OFF');
        saveOptions();
      });

      jQuery('#pbSalvageMainCity').change(function()
      {
        ThroneOptions.salvageMainCity = this.value;
        saveThroneOptions();
      });

      jQuery('#pbSalvageToMainLowLimit').change(function()
      {
        ThroneOptions.salvageToMainLowLimit = this.value;
        saveThroneOptions();
      });
      
      jQuery('#pbSalvageToMainCity').change(function()
      {
        ThroneOptions.salvageToMainCity = this.checked;
        saveThroneOptions();
      });

      t.togOpt ('ThroneSpaceWarning', 'ThroneSpaceWarning');
      t.changeOpt ('throneSaveNum', 'throneSaveNum'); 
      t.changeOpt ('ThroneSpaceCount', 'ThroneSpaceCount');
      t.changeOpt ('pbSalvageInterval', 'salvageInterval');
    } catch (e) {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  Upgrade_Enhance :function (){
    var t = Tabs.Throne;  
    try {    
      var m = '';
      m += '<DIV style="height:22px; vertical-align:middle;" id=pbTowrtDivF class=pbStat>';
      m += '<span style="float:left;">';
      m += '<INPUT id=Enable type=submit value="Queue = ' + (ThroneOptions.Active == false ? 'OFF' : 'ON') + '">';
      m += '</span>ADD UPGRADE OR ENHANCE TO QUEUE<span style="float:right;"><INPUT id=ShowHistory type=submit value="History"></span>';
      m += '</div>';
      m += '<TABLE class=ptTab>';
      m += '<TR><TD>Throne items:</td><TD><SELECT id=ThroneItems type=list></select></td>';
      m += '<TD><INPUT id=addEnhance type=submit value="Enhance"></td>';
      m += '<TD><INPUT id=addUpgrade type=submit value="Upgrade"></td>';
      m += '<TD><DIV id=ShowHoover></div></td>';
      m+='</tr>';
      m+='</table><br/>';
      m+= '<DIV id=pbTowrtDivF class=pbStat>STATUS</div>';
      m+= '<br/><DIV id=ShowStatus></div></p>';
      m+= '<DIV id=ShowTries></div><br/>';
      m+= '<DIV id=ShowStones></div><br/>';
      m+= '<DIV id=pbTowrtDivF class=pbStat>UPGRADE INFO</div>';
      m+= '<br/><DIV id=ShowInfo></div><br/>';
      m+= '<DIV id=pbTowrtDivF class=pbStat>QUEUE</div>';
      m+= '<br/><DIV id=ShowQueueDiv style="height:200px; overflow-x:auto; overflow-y:scroll;"></div>';
      t.Overv.innerHTML = m;
      
      document.getElementById('ThroneItems').options.length=0;
      for (i in unsafeWindow.kocThroneItems) 
      {
        var o = document.createElement("option");
        o.text = unsafeWindow.kocThroneItems[i]["name"];
        o.value = unsafeWindow.kocThroneItems[i]["id"];
        document.getElementById("ThroneItems").options.add(o);
      }
      
      document.getElementById('addEnhance').addEventListener ('click', function () { t.addToQueue(document.getElementById('ThroneItems').value,"Enhance"); },false);
      document.getElementById('addUpgrade').addEventListener ('click', function () { t.addToQueue(document.getElementById('ThroneItems').value,"Upgrade"); },false);

      document.getElementById('ThroneItems').addEventListener ('change', function () { t.paintHoover(); }, false);
    
      document.getElementById('Enable').addEventListener('click', function(){t.toggleThroneState()} , false);
      document.getElementById('ShowHistory').addEventListener('click', function(){t.PaintHistory()} , false);
  
      if (ThroneOptions.Items.length ==0) 
      {
        document.getElementById('ShowStatus').innerHTML = "No items in queue!!";
      } 
      else 
      {
        if (ThroneOptions.Active && Seed.queue_throne.end == undefined) 
        { 
          document.getElementById('ShowStatus').innerHTML = "Waiting for timer...";
        }
      
        if (ThroneOptions.Active && Seed.queue_throne.end != undefined) 
        {
          t.setRepairTimer = setInterval (t.repairTimerUpdate,1000);
        }
        
        if (!ThroneOptions.Active && Seed.queue_throne.end != undefined) 
        {
          t.setRepairTimer = setInterval (t.repairTimerUpdate,1000); 
        }
      
        if (!ThroneOptions.Active && Seed.queue_throne.end == undefined) 
        {
          document.getElementById('ShowStatus').innerHTML = "Auto Upgrade/Enhance/Repair is OFF.";
        }
      } 
      
      if (ThroneOptions.Tries > 0) 
      {
        jQuery('#ShowTries').html("Tries: " + ThroneOptions.Tries);
      } 
      else 
      {
        jQuery('#ShowTries').html("Tries: ---");
      }
    
      if (ThroneOptions.Items.length > 0) 
      {
        t.paintInfo();
        t.PaintQueue();
      }
    
    } 
    catch (e) 
    {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  organizer : function ()
  {
    var t = Tabs.Throne;
    
    // setup the lists for tables, chairs, etc.
    t.fillLists();

    // setup the tab
    var m = '<div align=left>';

    var effects = [];
    
    for (e in CM.thronestats.effects)
    {
      var effectName = CM.thronestats.effects[e][1].split(" Debuff")[0];
      
      if (effects.indexOf(effectName) < 0) 
      {
        effects.push(effectName);
      }
    }

    m += '<TABLE class=ptTab><tr align=center><td>Preset: <select id="PresetList">';
    m += '<option value="0">--Presets--</option>';

    for (k= 1; k <= Seed.throne.slotNum; k++)
    {
      m += '<option value="'+k+'"> Preset:  '+ k +'</option>';
    }
    
    m += '</select></td>';
    m += '<TD><INPUT id=testSalvage type=submit value=" Test Salvage "/></td><td id=trDelResults></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>';
    m += '<a class="button20" id=loadThroneItems><span>Load Throne Items from Web</span></a><input id=pbThroneItemsUrl size="50" type="text" value="' + Options.itemUpdateUrl + '"/>';
    m += '</td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>';
    m += '<a class="button20" id=exportPlayerThrone><span>Export Player Throne Items for Web</span></a>';
    m += '</td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Player: <select id="playerSelect"><option value="0">Own</option><option value="1">Combine all</option>';
    for(player in playerThroneItems)
    {
      if(Options.attackersRange[player] && Options.attackersRange[player].name)
      {
        m += '<option value="' + player + '"> '+ Options.attackersRange[player].name +'</option>'
      }
    }
    
    m += '</td>';
    m += '</tr>';
    m += '<tr align=center><td><div><span>Sort: <select id="trSortList">';

    m += '<option value="none">--Effect--</option>';
    for (k in effects)
    {
      m += '<option value="' + effects[k] + '">'+ effects[k] +'</option>';
    }
    m += '</select></span></div></td>';

    m += "<td> <select id='trSortType'>";
    m += "  <option value='both'>Either</option>";
    m += "  <option value='buff'>Buff</option>";
    m += "  <option value='debuff'>Debuff</option>";
    m += "</select></td>";

    m += '<td><INPUT id=trSortInactive type=checkbox '+ (  t.sortInactive ?' CHECKED':'') +'/> Include Inactive</td>';
    m +='</tr></table></div>';

    m += "<div id='trScrollDiv' style='max-height:540px; height:540px; overflow-y:scroll;'>";
    var ii = Math.max(t.itemLists['chair'].length, t.itemLists['table'].length, t.itemLists['window'].length, t.itemLists['banner'].length, t.itemLists['advisor'].length, t.itemLists['trophy'].length);

    m += "<div id='trTableDiv' style='width: 100%;'>";
    m += '<TABLE id=trDisplayTable width=100% height=0% class=trTab>';
    m += "<tr align=center><th>Chairs</th><th>Tables</th><th>Windows</th><th>Banners</th><th>Advisors</th><th>Trophies</th><th>Candelabras</th></tr>";
    m += '</table></div>';
    m += '</div>';
    m += '</div>';

    t.Overv.innerHTML = m;
    t.paintTable();

    jQuery("#PresetList").click( function() {t.selectPreset( jQuery(this).val());});
    jQuery("#testSalvage").click(function() {t.testSalvage();});

    jQuery('#prepareThroneItems').click(function()
    {
      t.prepareThroneItems();
    });
    
    jQuery('#loadThroneItems').click(function()
    {
      setBusy(true);

      var url = jQuery('#pbThroneItemsUrl').val();
      if(!url)
      {
        alert("You need to enter a url!");
      }
      else
      {
        Options.itemUpdateUrl = url;
        saveOptions();
        setTimeout(t.loadFromNet(url), 100);
      }
    });

    jQuery('#exportPlayerThrone').click(function()
    {
      setBusy(true);
      var exportThronePopup = null;
      exportThronePopup = new pbPopup('pbPlayerThronePopup', 0, 0, 600, 500, true, function() {clearTimeout (1000);});
      var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto">';
      m += '<textarea rows=30 cols=100 id=throneInfo></textarea>';
      m += '</div>';       
      exportThronePopup.getTopDiv().innerHTML = '<td><b>Export Player Throne Information</b></td>';
      exportThronePopup.getMainDiv().innerHTML = m;
      exportThronePopup.show(true)  ;
      setTimeout(function()
      {
        jQuery('#throneInfo').text(JSON2.stringify(playerThroneItems, null, 2));
        setBusy(false);
      }, 400);
    });

    jQuery("#playerSelect").change(function() 
    {
      setBusy(true);
      t.selectedPlayer = jQuery(this).val();
      
      logit("Throne: change player in organizer - " + jQuery(this).val());
      setTimeout(function()
      {
        t.fillLists(t.selectedPlayer);
        t.updateOrganizerDisplay();
        setBusy(false);
      }, 400);
    });
    
    // default to highlight the active preset
    t.selectPreset(Seed.throne.activeSlot);
    document.getElementById ('PresetList').value = Seed.throne.activeSlot;

    jQuery("#trSortList").change( function () 
    { 
      setBusy(true);
      t.sortEffect = jQuery(this).val();

      setTimeout(function()
      {
        if(t.selectedPlayer == 1)
        {
          t.fillLists(t.selectedPlayer);
        }
        t.updateOrganizerDisplay();
        setBusy(false);
      }, 400);
    });

    jQuery("#trSortType").change( function()
    {
      setBusy(true);
      t.sortType = jQuery(this).val();

      setTimeout(function()
      {
        if(t.selectedPlayer == 1)
        {
          t.fillLists(t.selectedPlayer);
        }
        t.updateOrganizerDisplay();
        setBusy(false);
      }, 400);
    });

    jQuery("#trSortInactive").change( function()
    {
      setBusy(true);

      setTimeout(function()
      {
        if(t.selectedPlayer == 1)
        {
          t.fillLists(t.selectedPlayer);
        }
        t.updateOrganizerDisplay();
        setBusy(false);
      }, 400);
    });
  },
  
  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  prepareThroneItems : function()
  {
    var t = Tabs.Throne;
    
    for(playerId in playerThroneItems)
    {
      var playerItems = playerThroneItems[playerId];
      
      for(itemId in playerItems)
      {
        var item = playerItems[itemId];
      }
    }
  },
  
  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  loadFromNet : function(url)
  {
    var t = Tabs.Throne;
    
    getJSONfromURL(url, t.loadItemUpdates) 
    setBusy(false);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  loadItemUpdates : function(resultValue)
  {
    var t = Tabs.Throne;
    var count = 0;
    
    logit("Throne Test: - " + JSON2.stringify(resultValue, null, 2));
    
    playerThroneItems = resultValue;
    savePlayerThrone();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateOrganizerDisplay : function ()
  {
    var t = Tabs.Throne;
    
    // setup the lists for tables, chairs, etc.
    //t.fillLists();
    t.sortLists()
    t.paintTable();
    t.selectPreset(Seed.throne.activeSlot);
    document.getElementById ('PresetList').value = Seed.throne.activeSlot;
  },

  showNext : function () 
  {
    var t = Tabs.Throne;
    
    if (t.panelId < 0) 
      return;
    
    var X = unsafeWindow.kocThroneItems[t.panelId];
    var V = "next";
    var P = t.panelType;

    var bump = t.panelNextLevel;

    if (P == "enhance")
    {
      if ( (X.quality + bump ) > 5)
      {
        bump = 5 - X.quality;
      }
    }
    else if ( (X.level + bump) > 10)
    {
      bump =  10 - X.level;
    }

    var R = [],
    Q, Y, S, U, N = {},
    T, W;
    if (V == "next") 
    {
      if (P == "enhance") 
      {
        X.quality += bump;
        jQuery("#nextStatContainer span").html('<span> ' + X.createPrefix() + ' </span>');
      } 
      else 
      {
        if (P == "upgrade") 
        {
          X.level += bump;
          jQuery("#nextStatContainer span").html('<span> Level ' + X.level + ' </span>');
        }
      }
    }
    
    jQuery.each(X.effects, function (Z, aa) 
    {
      Q = +(Z.split("slot")[1]);
      Y = CM.thronestats.effects[aa.id];
      S = CM.thronestats.tiers[aa.id][aa.tier];
      U = +(S.base) + ((X.level * X.level + X.level) * +(S.growth) / 2);
      U = U.toFixed(2);
      N[aa.id] = {};
      N[aa.id].percent = U;
      N[aa.id].name = Y[1];
      
      if (Q % 2 == 0) 
      {
        T = "even"
      } 
      else 
      {
        T = "odd"
      }
      
      if (Q <= X.quality) 
      {
        if (U > 1) 
        {
          R.push("<li class='" + T + "'>" + Y[1] + " +" + U + "%</li>")
        } 
        else 
        {
          R.push("<li class='" + T + "'>" + Y[1] + " " + U + "%</li>")
        }
      } 
      else 
      {
        R.push("<li class='disabled " + T + "'>" + Y[1] + " + " + U + "%</li>")
      }
    });
    
    if (V == "next") 
    {
      if (P == "enhance") 
      {
        X.quality -= bump
      } 
      else 
      {
        if (P == "upgrade") 
        {
          X.level -= bump;
        }
      }
    }
    
    if (V === "next") 
    {
      if (CM.ThronePanelController.isLastLevel(X, P)) 
      {
        W = jQuery("<div/>").addClass("lock").attr("id", "lockedStatIcon");
        jQuery("#nextStatContainer").append(W)
      } 
      else 
      {
        jQuery("#lockedStatIcon").remove()
      }
    }
    
    t.panelNextLevel++;
    jQuery("#thronePanelStat2").html(R.join(""));
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  buildList : function()
  {
    var list = [];
    
    return list;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  testSalvage : function() 
  {
    var t = Tabs.Throne;
    var toDelete = t.buildList(true);

    jQuery('#trDelResults').html("<div> " + toDelete.length + " items targeted for deletion</div>");

    for (i = 0; i < toDelete.length ; i++)
    {
      var item = unsafeWindow.kocThroneItems[toDelete[i]];
      
      if (item.isBroken || item.isEquipped)
      {
        t.selectCard(toDelete[i], "orange");
      }
      else
      {
        t.selectCard(toDelete[i], "red");
      }
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintTable : function() 
  {
    // fill in the table
    var t = Tabs.Throne;
    var m = "";
    var mm;
    var tab = document.getElementById('trDisplayTable');
    var ii = Math.max(t.itemLists['chair'].length, t.itemLists['table'].length, t.itemLists['window'].length, t.itemLists['banner'].length, t.itemLists['advisor'].length, t.itemLists['trophy'].length, t.itemLists['candelabrum'].length);
    ii = Math.min(ii, 20);
    
    m += "<tr align=center valign=top><th width=17%>Chairs</th><th width=17%>Tables</th><th width=17%>Windows</th><th width=17%>Banners</th><th width=16%>Advisors</th><th width=16%>Throphies</th></tr>";
    for (var k= 0; k < ii ; k++)
    {
      mm = '<TR  align=left valign=top>';
      for (i in t.itemTypes)
      {
        var item = t.itemLists[i][k];
        var item_num = 0;
        var id="card";
        if (item != null)
        {
          id += item.id;
          item_num = item.id;
        }
        mm += '<TD style="border: 4px solid white;" id="' + id +'" >';
        mm += t.buildCard(item);
        mm += '</TD>';
      }
      mm += '</TR>';
      m+= mm;
    }

    tab.innerHTML = m;
    // repair the height/width caused by the 2d transform
    var d = document.getElementById ('trTableDiv');
    var table = document.getElementById ('trDisplayTable');
    var nodes = table.getElementsByTagName('td');

    for (n=0; n < nodes.length; n++)
    {
      var d2 = nodes[n].childNodes[0];
      var h = d2.offsetHeight;
      var w = d2.offsetWidth;
      d2.style.height = (TABLE_SCALE * h) + "px";
      d2.style.width  = (TABLE_SCALE * w) + "px";
    }

    jQuery(".trCardDisp").click( function( A)
    {
      var theId = jQuery(this).attr("id").split("trCardItem")[1];

      if ( jQuery(this.tooltipDiv).length === 0) 
      {
        var i = document.createElement("div");
        i.id = unsafeWindow.Tooltip.tooltipDiv;
        i.className = "tooltipDiv";
        document.body.appendChild(i);
        m = jQuery(this.tooltipDiv);
        jQuery(m).css(unsafeWindow.Tooltip.cssStyles);
      }
      unsafeWindow.cm.ContextualMenuThrone.renderMenu( jQuery(this), unsafeWindow.kocThroneItems[theId]);
    });
    
    jQuery("div.trCard").removeClass("blueBorder2");
    jQuery("div.trCard").removeClass("greenBorder2");
    jQuery("div.trCard").removeClass("yellowBorder2");

    for (i = 0 ; i < t.SalvageArray.length ; i++) 
    {
      jQuery("div#trCardItem" + t.SalvageArray[i]).find("div.trCard").addClass('redBorder2');
    }
    
    for (i = 0 ; i < ThroneOptions.Items.length ; i++)
    {
      jQuery("div#trCardItem" + ThroneOptions.Items[i].id).find("div.trCard").addClass('yellowBorder2');
    }
 
    for (i = 0 ; i < ThroneOptions.protectList.length ; i++)
    {
      jQuery("div#trCardItem" + ThroneOptions.protectList[i]).find("div.trCard").addClass('greenBorder2');
    }
    // for (ii in queueData.list) 
    // {
      // var list_item = queueData.list[ii];
      
      // if (!list_item) 
        // continue;
      
      // if (list_item.status != "complete") 
      // {
        // var id = list_item.item;
        
        // if (list_item.action == "upgrade") 
          // jQuery("div#trCardItem" + id).find("div.trCard").addClass("blueBorder2");
        
        // if (list_item.action == "enhance") 
          // jQuery("div#trCardItem" + id).find("div.trCard").addClass("yellowBorder2");
      // }
    // }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  selectPreset : function (p)
  {
    var t = Tabs.Throne;
    // t.clearCards();
    t.clearHighlights();
    var equipedItems = Seed.throne.slotEquip[p];
    
    if (equipedItems != null)
    {
      for (ll =0; ll < equipedItems.length; ll++)
      {
        t.selectCard(equipedItems[ll], "green");
      }
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fillLists : function (player)
  {
    player = player || 0;
    
    var items = {};
    
    var t = Tabs.Throne;

    logit("Throne: fill item list in organizer - " + player);

    for (i in t.itemTypes)
    {
      t.itemLists[i] = new Array;
    }

    logit("Throne: [Organizer] Sort - " + t.sortEffect);
    if(player == 1)
    {
      for(itemId in unsafeWindow.kocThroneItems)
      {
        if(unsafeWindow.kocThroneItems.hasOwnProperty(e))
        {
          item = unsafeWindow.kocThroneItems[itemId];
          if(t.matchingItem(item))
          {
            items[itemId] = item;
            item.player = "Me";
          }
        }
      }
      for(playerId in playerThroneItems)
      {
        logit("Throne: adding - " + playerId + " items");
        for(itemId in playerThroneItems[playerId])
        {
          item = playerThroneItems[playerId][itemId];
          if(t.matchingItem(item))
          {
            logit("Throne: added - " + itemId);
            items[itemId] = item;
            item.player = playerId;
          }  
        }
      }
    }
    else if(player == 0 || !playerThroneItems[player])
    {
      items = unsafeWindow.kocThroneItems;
    }
    else
    {
      items = playerThroneItems[player];
    }
    
    for (k in items) 
    {
      var throne_item = items[k];
      
      if (throne_item.isEquipped)
        t.itemLists[throne_item.type].unshift(throne_item);
      else
        t.itemLists[throne_item.type].push(throne_item);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  matchingItem : function(item)
  {
    var t = Tabs.Throne;
    var match = false;
    
    var effectB = t.sortEffect;
    var effectD = t.sortEffect + " Debuff";

    for(i = 1 ; i < 6 ; i++)
    {
      var effectId = item.effects["slot" + i].id;
      effectName = CM.thronestats.effects[effectId][1]
      
      if((t.sortType == "buff" && effectB == effectName) || 
         (t.sortType == "debuff" && effectD == effectName) ||
         (t.sortType == "both" && ((effectB == effectName) || (effectD == effectName))))
      {
        match = true;
        
        break;
      }  
    }
    
    return match;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sortLists : function ()
  {
    var t = Tabs.Throne;
    t.sortInactive = jQuery("#trSortInactive").attr('checked');
    
    for (i in t.itemLists)
    {
      t.itemLists[i].sort( function (item1, item2) 
      {
          return t.sortValue(item2) - t.sortValue(item1);
      });
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sortValue : function (item)
  {
    var t = Tabs.Throne;
    var retValue = 0.0;
    for (e in item.effects)
    {
      var N = item.effects[e];
      var effect=CM.thronestats.effects[N.id][1];
      var tier=CM.thronestats.tiers[N.id][N.tier];
      var B=+(e.split("slot")[1]);

      if (B> item.quality && !t.sortInactive)
      {
        return +retValue;
      }

      var percent=+(tier.base+((item.level*item.level+item.level)*tier.growth*0.5));  
      
      if ( (effect == (t.sortEffect + " Debuff")) && (t.sortType != "buff"))
      {
        retValue -= percent;
      }
      else if (effect == t.sortEffect && t.sortType != "debuff")
      {
        retValue += percent;
      }
    }
    
    return +retValue;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  clearHighlights : function()
  {
    var t = Tabs.Throne;

    for (k in unsafeWindow.kocThroneItems)
    {
      var throne_item = unsafeWindow.kocThroneItems[k];
      t.selectCard(throne_item.id, "white");
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  selectCard : function(itemId, color)
  {
    var t = Tabs.Throne;
    var item = unsafeWindow.kocThroneItems[itemId];

    t.selectedItems[item.type] = itemId;
    td = document.getElementById( "card"+itemId);
    
    if (td)
    {
      td.style.borderColor = color;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  clearCards : function()
  {
    var t = Tabs.Throne;
    
    for (k in t.selectedItems)
    {
      var td = document.getElementById( "card" + t.selectedItems[k]);
      if (td)
      {
        td.style.borderColor = "white";
      }
    }
    t.selectedItems = [];
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  buildCard : function(I)
  {
    var quality = ["Simple", "Common", "Uncommon", "Rare", "Epic", "Wonderous"];
    var t = Tabs.Throne;
    var D = [];
    var w = CM.thronestats.mightByQuality;
    var z = CM.thronestats.mightByLevel;
    
    if (I == null)
    {
      D.push("<div>");
      D.push("</div>");
      
      return D.join("");
    }
    
    D.push("<div class='trCardDisp' id='trCardItem" + I.id + "' style='overflow: visible; position: relative; left: 0px; top: 0px; -moz-transform: scale(" + TABLE_SCALE + ", "+ TABLE_SCALE + "); -moz-transform-origin: 0% 0%;  -webkit-transform: scale(" + TABLE_SCALE + ", "+ TABLE_SCALE + ");  -webkit-transform-origin: 0% 0%;);'>");
    
    if (I.isBroken)
    {
      D.push(" <div class='cardOverlay semi_transparent rot45'> Broken </div>");
    }
    
    var name = "";
    
    if(!I.name)
    {
      var itemTitle = CM.thronestats.effects[I.effects.slot5.id]["4"];

      name = quality[I.quality] + " " + I.type + " of " + itemTitle + " +" + I.level;
      if(I.player)
      {
        if(Options.attackersRange[I.player])
        {
          if(Options.attackersRange[I.player].name)
          {
            name += " [" + Options.attackersRange[I.player].name + "]";
          }
          else
          {
            name += " [" + I.player + "]";
          }
        }
        else
        {
          name += " [" + I.player + "]";
        }
      }
    }
    else
    {
      name = I.name;
    }
    
    // I.createPrefix()
    // var I = new cm.ThroneItemModel(item.id, item);
    D.push(" <div class='trCard' style='white-space: normal; padding: 0px;'> ");
    D.push("<div class='section' style='overflow: visible;' id = 'idsection'>");
    D.push(" <div class='title "+ "2345" + "' style='text-transform: capitalize;'> ");
    D.push(name);
    D.push(" </div> ");
    D.push(" <div class='description'> ");
    D.push(" <div class='portrait "+ I.faction + " " + I.type + "'> </div> ");
    D.push("<ul>");
    D.push("<li>" + uW.g_js_strings.commonstr.faction + ": " + I.faction + "</li>");
    D.push("<li>" + uW.g_js_strings.commonstr.quality + ": " + quality[I.quality]  + "</li>");
    D.push("<li>" + uW.g_js_strings.commonstr.type + ": " + I.type + "</li>");
    D.push("<li>" + uW.g_js_strings.commonstr.level + ": " + I.level + "</li>");
    D.push("<li>" + uW.g_js_strings.commonstr.might + ": " + (w[I.quality].Might + z[I.level].Might) + "</li>");
    D.push("</ul>");
    D.push(" </div> ");
    D.push(" <ul> ");

    for (M in I.effects)
    {
      var N = I.effects[M];
      effect=CM.thronestats.effects[N.id];
      tier=CM.thronestats.tiers[N.id][N.tier];
      percent=+(tier.base+((I.level*I.level+I.level)*tier.growth*0.5));
      percent=(percent>0)?"+"+percent:+percent;
      percent= parseFloat(percent).toFixed(2);
      // percent=Math.ceil(percent);
      css=(M%2===0)?"even":"odd";
      B=+(M.split("slot")[1]);
      if(B<=I.quality)
      {
        D.push(" <li class='effect "+css+"'> "+percent+"% "+effect[1]+" </li> ");
      }
      else
      {
        D.push(" <li class='effect disabled "+css+"'> "+percent+"% "+effect[1]+" </li> ");
      }
    }
    
    D.push(" </ul> ");
    D.push(" </div> ");
    D.push(" </ul> ");
    D.push(" </div> ");
    D.push(" </div> ");
    
    return D.join("");
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  EnhancedSalvage :function ()
  {
    var t = Tabs.Throne;  

    try 
    {      
      var m = '';

      var m = '<Div><DIV id=trSalvage class=pbStat>AUTOMATED SALVAGE</div>';

      m += "<div id='trInfoArea'>";
      m += '</div>';

      m += "<div id='trRulesCreate' class='trRuleCreate'>";

      // rules definition
      m += '<TABLE class=trTabDef width=100% class=trTabPad style="padding-left: 10px;">';
      m += '<tr><td>  <b>Define the TR items to keep: </b> </td>';

      m += '<td alight="left"><div><span>Faction: <select id="trFactionType">';
      m += '  <option value="any">Any</option>';
      m += '  <option value="fey">Fey</option>';
      m += '  <option value="briton">Briton</option>';
      m += '  <option value="druid">Druid</option>';
      m += '</select></span></div></td>';
      m += '<td alight="left"><div><span>Card type: <select id="trCardType">';
      m += '  <option value="any">Any</option>';
      m += '  <option value="chair">Chair</option>';
      m += '  <option value="table">Table</option>';
      m += '  <option value="window">Window</option>';
      m += '  <option value="banner">Banner</option>';
      m += '  <option value="advisor">Advisor</option>';
      m += '  <option value="trophy">Trophy</option>';
      m += '  <option value="candelabrum">Candelabrum</option>';
      m += '</select></span></div></td>';
      m += '<td align="right"><INPUT id=trAddRule type=submit value="Create Rule"/></td>';
      m += '</tr></table>';
      m += '<TABLE  class=trTabPad width=100% id="trConditionTable"  style="padding-left: 5px;">';
      m += '<tr><td align=left colspan=1><INPUT id=trAddRow type=submit value="Add Row"/></td>';
      m += '<td></td><td></td><td></td><td></td><td></td></tr>';
      m += '</table>';
      m += '</div><hr/>';
      m += '<div id="trSalvStatus" style="text-align: center;" >Loading ... </div><hr/>';
      m += '<div class=trRulePane>';
      m += '<div align=center> <b> Salvager will keep items matching any of these rules </b></div>';
      m += "<div id='trRuleDisplay' style=' max-height:475px; height:500px; overflow-x: auto; overflow-y:scroll;'>";
      m += '</div></div>';
      t.Overv.innerHTML = m;

      t.createRow();
      t.buildRuleDisplay();

      document.getElementById ('trAddRow').addEventListener ('click', function() {t.createRow(); logit("Throne: trying to add new row");}, false);
      document.getElementById ('trAddRule').addEventListener ('click', function() {t.createRule();}, false);
            
    }
    catch(e)
    {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  createRow : function()
  {
    var t = Tabs.Throne;
    
    var table = document.getElementById('trConditionTable');
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount-1);
    var rowId = "r" + t.rowNum;
    t.rowNum++;
    row.id = rowId;

    var h  = "<td> <select id='" + rowId + "sel1'> <option value='true'> </option> <option value='false'>NOT</option></select></td>";
    h += "<td> <select id='" + rowId + "sel2'>";
    h += "  <option value='1'>1x</option>";
    h += "  <option value='2'>2x</option>";
    h += "  <option value='3'>3x</option>";
    h += "  <option value='4'>4x</option>";
    h += "  <option value='5'>5x</option>";
    h += "</select></td>";
    h += "<td> <select id='" + rowId + "sel3'>";
    h += "</select></td>";
    h += "<td> <select id='" + rowId + "sel4'>";
    h += "  <option value='e'>Either</option>";
    h += "  <option value='b'>Buff</option>";
    h += "  <option value='d'>Debuff</option>";
    h += "</select></td>";

    h += "<td> Slots: ";
    h += "  <input type=checkbox value='1' checked=true id='" + rowId + "slot1'/>1";
    h += "  <input type=checkbox value='2' checked=true id='" + rowId + "slot2'/>2";
    h += "  <input type=checkbox value='3' checked=true id='" + rowId + "slot3'/>3";
    h += "  <input type=checkbox value='4' checked=true id='" + rowId + "slot4'/>4";
    h += "  <input type=checkbox value='5' checked=true id='" + rowId + "slot5'/>5";
    h += "</td>";

    row.innerHTML = h;

    var effects = [];

    for (e in CM.thronestats.effects)
    {
      if(CM.thronestats.effects.hasOwnProperty(e))
      {
        var effectName = CM.thronestats.effects[e][1].split(" Debuff")[0];
        
        if (effects.indexOf(effectName) < 0 && effectName.length < 40) 
        {
          effects.push(effectName);
        }
      }
    }

    var select = document.getElementById(rowId + "sel3");
    for(index in effects) 
    {
      if(effects[index].length < 40) 
      {
        select.options.add(new Option(effects[index], effects[index]));
      }
    }

    var c = row.insertCell(5);
    var btn = document.createElement("input");
    btn.type = "submit";
    btn.value = "X";
    btn.onclick = function () { t.removeRow(row);};
    c.appendChild(btn);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  createRule : function()
  {
    var t = Tabs.Throne;
    
    t.readRows();
    t.buildRuleDisplay();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  setSalvageLevel : function(level)
  {
    salvageData.minQuality = level;
    saveSalvageData();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  buildRuleDisplay : function ()
  {
    var t = Tabs.Throne;
    var rd = document.getElementById('trRuleDisplay');

    var m = '<TABLE  width=100% class="trTabPad">';

    for (i =0; i < salvageData.ruleSet.length; i++)
    {
      var rule = salvageData.ruleSet[i];

      m += '<tr>';
      m += "<td width=90%><div class='trRule'>";

      m += "Type: " + rule.type;
      m += " Faction: " + rule.faction;

      for (ii = 0; ii < rule.conditions.length; ii++)
      {
        var condition = rule.conditions[ii];

        if (ii == 0 )
        {
          m += "<br> Item";
        }
        else
        {
          m += "<br> <u>and</u>";
        }

        if (condition.mustHave != "false")
        {
          m += " must have ";
        }
        else
        {
          m += " must NOT have ";
        }

        m += condition.number + "x ";
        m += condition.effect + " ";

        if (condition.buffType == "b")
        {
          m += "buff ";
        }
        else if (condition.buffType == "d")
        {
          m += "debuff ";
        }
        else
        {
          m += "buff or debuff ";
        }

        m += " in slot(s): ";

        for (j = 0; j < condition.slots.length; j++)
        {
          if (condition.slots[j] ) 
          {
            m += (j+1) + " ";
          }
        }
      }
      
      m += "</div></td>";
      m += "<td width=20%><INPUT id=trDelRule" + i + " type=submit value='Delete Rule' /></td>";
      m += '</tr>';
    }
    
    m += '</table>';

    rd.innerHTML = m;

    for (var j=0; j < salvageData.ruleSet.length; j++)
    {
      document.getElementById('trDelRule' +j).v1 = j;
      document.getElementById('trDelRule' +j).addEventListener ('click', function() { t.deleteRule(this.v1)}, false);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  // Description   : delete a rule from the ruleset
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  deleteRule : function(i)
  {
    var t = Tabs.Throne;

    salvageData.ruleSet.splice(i,1);
    saveSalvageData();
    t.buildRuleDisplay();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  readRows : function()
  {
    var t = Tabs.Throne;
    var table = document.getElementById('trConditionTable');
    var rowCount = table.rows.length;

    var cType = document.getElementById('trCardType').value;
    var faction = document.getElementById('trFactionType').value;

    var conditions = [];

    for (i=0; i < table.rows.length; i++)
    {
      var row = table.rows[i];
      if (row.id)
      {
        var s1 = document.getElementById(row.id + "sel1");
        var s2 = document.getElementById(row.id + "sel2");
        var s3 = document.getElementById(row.id + "sel3");
        var s4 = document.getElementById(row.id + "sel4");

        var slots = [];
        for (j =1; j <= 5; j++)
        {
          var ch = document.getElementById(row.id + "slot" + j);
          slots.push(ch.checked);
        }

        var c = new Condition(s1.value, s2.value, s3.value, s4.value, slots );
        conditions.push(c);
      }
    }
    
    var rule1 = new Rule(cType, faction, conditions);
    t.addRule(rule1);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  removeRow : function(row)
  {
    var table = document.getElementById('trConditionTable');

    for (i=0; i < table.rows.length  ; i++ )
    {
      if (table.rows[i] == row)
      {
        table.deleteRow(i);
        break;
      }
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // add a new rule
  addRule : function(rule)
  {
    salvageData.ruleSet.push(rule);
    saveSalvageData();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // returns true if the item should be saved and not salvaged
  applyRules : function(id) 
  {
    var t = Tabs.Throne;

    for (r in salvageData.ruleSet)
    {
      var rule = salvageData.ruleSet[r];
      if ( rule.applyRule(id)) return true;
    }
    
    return false;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  AutoUpgrade :function ()
  {
    var t = Tabs.Throne;  
    
    try 
    {      
      var m = '';

      m += '<DIV id=pbTowrtDivF class=pbStat>Auto Token Update</div>';
      m += '<table width=100% height=0% class=pbTab cellspacing=10 cellpadding=5>';
      m += '<tr>';
      m += '<td colspan=2>Leave at least <INPUT type=text size=6 value='+ Options.autoItemUpgradeSaveAmount +' id=pbAutoItemUpgradeSaveAmount /> Aetherstone per city</td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td colspan=2>Leave at least <INPUT type=text size=3 value='+ Options.autoTrUpgradeLeaveTokens +' id=pbAutoTrUpgradeLeaveTokens /> tokens</td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td colspan=2>Max tokens to use <INPUT type=text size=3 value='+ Options.autoItemUpgradeMaxTokens +' id=pbAutoItemUpgradeMaxTokens /> (zero for no limit)</td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td style="width:50px">Tokens Available:</td><td><div id=pbTokenCount>...</div></td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td style="width:50px">Tries:</td><td><div id=pbAutoTokenCount>0</div></td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td style="width:50px">Status:</td><td><div id=pbAutoTokenStatus>Waiting...</div></td>';
      m += '</tr>';
      m += '<tr>';
      m += '<TD colspan=2><INPUT id=cancelAutoUpgrade type=submit value="Cancel Auto Token Upgrade"></td>';
      m += '</tr>';
      m += '</table>';
      m += '<DIV id=pbTowrtDivF class=pbStat>Aetherstone Status</div>';
      m += '<DIV id=ShowStones></div><br/>';

      t.Overv.innerHTML = m;
      
      t.paintAutoUpgradeData();
      
      // jQuery('#pbAutoItemUpgradeMaxTokens').keyup(function(event) 
      // { 
        // this.value = this.value.replace(/[^0-9\.]/g,'');
      // });

      jQuery('#pbAutoItemUpgradeMaxTokens').change(function() 
      { 
        Options.autoItemUpgradeMaxTokens = parseIntWithDefault(this.value, 0);
        saveOptions();
      });
      

      // jQuery('#pbAutoTrUpgradeLeaveTokens').keyup(function(event) 
      // { 
        // this.value = this.value.replace(/[^0-9\.]/g,'');
      // });

      jQuery('#pbAutoTrUpgradeLeaveTokens').change(function() 
      { 
        Options.autoTrUpgradeLeaveTokens = parseIntWithDefault(this.value, 0);
        saveOptions();
      });

      // jQuery('#pbAutoTrUpgradeLeaveTokens').bind("keyup change", function(event) 
      // { 
        // switch(event.type)
        // {
          // case "keyup":
            // this.value = this.value.replace(/[^0-9\.]/g,'');
            // break;
            
          // case "change":
            // Options.autoTrUpgradeLeaveTokens = parseIntWithDefault(this.value, 0);
            // if(this.value != Options.autoTrUpgradeLeaveTokens)
            // {
              // this.value = Options.autoTrUpgradeLeaveTokens;
            // }
            // saveOptions();
            // break;
        // }
      // });
      
      jQuery('#pbAutoItemUpgradeSaveAmount').bind("keyup change", function(event) 
      { 
        logit("Throne: [#" + event.target.id + "] event - " + event.type);
        switch(event.type)
        {
          case "keyup":
            this.value = this.value.replace(/[^0-9\.]/g,'');
            break;
            
          case "change":
            Options.autoItemUpgradeSaveAmount = parseIntWithDefault(this.value, 100000);
            if(this.value != Options.autoItemUpgradeSaveAmount)
            {
                this.value = Options.autoItemUpgradeSaveAmount;
            }
            saveOptions();
            break;
        }
      });
      
      jQuery('#cancelAutoUpgrade').click(function()
      {
        t.autoUpgradeStop = true;
      });
      
    } catch (e) {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintAutoUpgradeData : function()
  {
    var t = Tabs.Throne;
    
    jQuery('#pbTokenCount').text(Seed.items["i20005"]);
    jQuery('#pbAutoTokenCount').text(t.autoUpgradeTries);
    jQuery('#pbAutoTokenStatus').text(t.autoUpgradeMessage);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  Equip : function (status)
  {
    var t = Tabs.Throne;  

    try 
    {   
      var m = '<DIV id=pbTowrtDivF class=pbStat>EQUIP THRONE ITEMS</div><br>';
      m += '<table>';
      m += '<tr>';
      m += '<td>';
      m += 'Preset: <SELECT id=pbSourcePreset type=list></select><input type=submit id=deletePreset value="Delete"><input type=submit id=newPreset value="New"><input type=submit id=copyPreset value="Copy -->"><SELECT id=pbDestPreset type=list></select>&nbsp;&nbsp;&nbsp;<span id=status></span>';
      m += '</td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td>';
      m += '<input type=checkbox id=changePresetOnSelect ' + ((t.changePresetOnSelect == true) ? 'checked' : '') + '/> Change preset on selection change';
      m += '</td>';
      m += '</tr>';
      m += '<tr>';
      m += '<td>';
      m += 'Preset Name:<input id=presetName maxlength=20 size=20 type=text value=""/><span id=newNameHelp></span>';
      m += '</td>';
      m += '</tr>';
      m += '</table>';

      m += '<div>';
      m += '<table>';
      m += '<tr>';
      m += '<td>';
      m += '<TABLE id=pbbarbingfunctions width=100% height=0% class=pbEquip align=left>';
      
      for (k in t.ItemTypeList)
      {
        var y = t.ItemTypeList[k];
        if (typeof(y) == "string") 
        {
          what = y.toLowerCase();
          
          if (y == "Windows") 
          {
            y = "Window";
          }
          
          m+='<TR>';
          m+='<TD>'+ y +':&nbsp;&nbsp;<SELECT id='+ what +' type=list></select><br><div align=center><INPUT id="Equip'+ what +'" type=submit value="Equip">&nbsp;&nbsp;<INPUT id="Unequip'+ what +'" type=submit value="Unequip"></div></td>';
          m+='<TD><div align=left id="info'+ what +'"></div></td>';
          m+='</tr>';
        }
      }
      
      m += '</table>';
      
      m += '</td>';
      m += '<td>';
      m += '<div id=throneStats></div>';
      m += '</td>';
      m += '</tr>';
      m += '</table>';
      m += '</div>';
      
      t.Overv.innerHTML = m;

      if(status)
      {
        jQuery('#status').text(status);
      }
      
      jQuery('#changePresetOnSelect').change(function()
      {
        t.changePresetOnSelect = this.checked;
      });
      
      jQuery("#pbSourcePreset").html("");
      for (i = 1 ; i <= Seed.throne.slotNum ; i++)
      {
        jQuery("#pbSourcePreset").append(
          jQuery('<option></option>').val(i).html(i)
        );
      }
      
      for(customId in Options.customSlots)
      {
        jQuery("#pbSourcePreset").append(
          jQuery('<option></option>').val(customId).html(customId)
        );
      }

      jQuery("#pbDestPreset").html("");
      jQuery("#pbDestPreset").append(
        jQuery('<option></option>').val(0).html("---")
      );
      for (i = 1 ; i <= Seed.throne.slotNum ; i++)
      {
        jQuery("#pbDestPreset").append(
          jQuery('<option></option>').val(i).html(i)
        );
      }

      jQuery("#pbDestPreset").append(
        jQuery('<option></option>').val(100).html("[New Preset]")
      );
      
      for(customId in Options.customSlots)
      {
        jQuery("#pbDestPreset").append(
          jQuery('<option></option>').val(customId).html(customId)
        );
      }

      jQuery('#advisor, #banner, #chair, #table, #windows, #trophy, #candelabrum').change(function()
      {
        t.paintEquipItemInfo(this.value, this.id);
        
        logit('Throne: select item - ' + this.value);
        logit('Throne: slot items - ' + JSON2.stringify(t.activeThroneSlotItems, null, 2));
        if(t.activeThroneSlotItems.indexOf(+this.value) == -1)
        {
          logit('Throne: select item - not active ' + this.value + ', ' + this.id );
          jQuery('#Unequip' + this.id).attr('disabled', 'disabled');
          jQuery('#Equip' + this.id).removeAttr('disabled');
        }
        else
        {
          logit('Throne: select item - active ' + this.value + ', ' + this.id);
          jQuery('#Equip' + this.id).attr('disabled', 'disabled');
          jQuery('#Unequip' + this.id).removeAttr('disabled');
        }
      });
      
      document.getElementById("Equipadvisor").addEventListener ('click', function (){t.doEquip(document.getElementById("advisor").value)},false);
      document.getElementById("Equipbanner").addEventListener ('click', function (){t.doEquip(document.getElementById("banner").value)},false);
      document.getElementById("Equipchair").addEventListener ('click', function (){t.doEquip(document.getElementById("chair").value)},false);
      document.getElementById("Equiptable").addEventListener ('click', function (){t.doEquip(document.getElementById("table").value)},false);
      document.getElementById("Equipwindows").addEventListener ('click', function (){t.doEquip(document.getElementById("windows").value)},false);
      document.getElementById("Equiptrophy").addEventListener ('click', function (){t.doEquip(document.getElementById("trophy").value)},false);
      document.getElementById("Equipcandelabrum").addEventListener ('click', function (){t.doEquip(document.getElementById("candelabrum").value)},false);

      document.getElementById("Unequipadvisor").addEventListener ('click', function (){t.doUnequip(document.getElementById("advisor").value)},false);
      document.getElementById("Unequipbanner").addEventListener ('click', function (){t.doUnequip(document.getElementById("banner").value)},false);
      document.getElementById("Unequipchair").addEventListener ('click', function (){t.doUnequip(document.getElementById("chair").value)},false);
      document.getElementById("Unequiptable").addEventListener ('click', function (){t.doUnequip(document.getElementById("table").value)},false);
      document.getElementById("Unequipwindows").addEventListener ('click', function (){t.doUnequip(document.getElementById("windows").value)},false);
      document.getElementById("Unequiptrophy").addEventListener ('click', function (){t.doUnequip(document.getElementById("trophy").value)},false);
      document.getElementById("Unequipcandelabrum").addEventListener ('click', function (){t.doUnequip(document.getElementById("candelabrum").value)},false);

      jQuery("#pbSourcePreset").change(function ()
      {
        selectedSlot = parseIntWithDefault(this.value, 0);
        
        if(selectedSlot >= 1 && selectedSlot <= 8)
        {
          if(t.changePresetOnSelect)
          {
            t.doPreset(selectedSlot);
          }
          
          t.activeThroneSlot = selectedSlot;
          t.activeThroneSlotItems = Seed.throne.slotEquip[selectedSlot];
          t.customPreset = false;
          jQuery('#deletePreset').attr('disabled', 'disabled');
        }
        else
        {
          selectedSlot = this.value;
          t.activeThroneSlot = selectedSlot;
          t.activeThroneSlotItems = Options.customSlots[selectedSlot];
          logit("Throne : presets - activeThroneSlotItems" + JSON2.stringify(t.activeThroneSlotItems, null, 2));
          t.customPreset = true;
          t.fixPresetOrder(t.activeThroneSlotItems);
          jQuery('#deletePreset').removeAttr('disabled');
        }
        
        t.FillEquipLists();
        stats = t.myThroneItemStats(t.activeThroneSlotItems);
        t.displayThroneStats(stats);
      });

      jQuery('#deletePreset').attr('disabled', 'disabled');
      jQuery('#copyPreset').attr('disabled', 'disabled');
      jQuery('#newPreset').attr('disabled', 'disabled');

      jQuery("#pbDestPreset").change(function ()
      {
        jQuery('#newNameHelp').text('');
        
        if(this.value == 0)
        {
          jQuery('#copyPreset').attr('disabled', 'disabled');        
        }
        else if (this.value == 100)
        {
          var newPresetName = jQuery('#presetName').val();
          jQuery('#newNameHelp').text('<-- Enter new name');
          
          if(!newPresetName || Options.customSlots[newPresetName])
          {
            jQuery('#copyPreset').attr('disabled', 'disabled');        
          }
          else
          {
            jQuery('#copyPreset').removeAttr('disabled');        
          }
        }
        else
        {
          jQuery('#copyPreset').removeAttr('disabled');        
        }
      });
      
      jQuery('#presetName').keyup(function()
      {
        if(jQuery("#pbDestPreset").val() == 100)
        {
          if(!Options.customSlots[this.value])
          {
            jQuery('#copyPreset').removeAttr('disabled');
          }
          else
          {
            jQuery('#copyPreset').attr('disabled', 'disabled'); 
          }
        }
        if(!Options.customSlots[this.value])
        {
          jQuery('#newPreset').removeAttr('disabled');
        }
        else
        {
          jQuery('#newPreset').attr('disabled', 'disabled'); 
        }
      });
      
      jQuery("#deletePreset").click(function()
      {
        var preset = jQuery("#pbSourcePreset").val();
        
        if(Options.customSlots[preset])
        {
          if(confirm('Delete preset - ' + preset +'?'))
          {
            delete Options.customSlots[preset];
            saveOptions();
            
            t.Equip("Preset deleted!");
          }
        }
      });

      jQuery("#newPreset").click(function()
      {
        var newPresetName = jQuery('#presetName').val()
        
        if(!Options.customSlots[newPresetName] && newPresetName)
        {
          Options.customSlots[newPresetName] = [];
          saveOptions();
          
          t.Equip("New preset created");
        }
      });
      
      jQuery("#copyPreset").click(function()
      {
        var preset = jQuery("#pbDestPreset").val();
        var sourcePreset = jQuery("#pbSourcePreset").val()
        
        if(preset == 100)
        {
          var newPresetName = jQuery('#presetName').val();
        
          if(!Options.customSlots[newPresetName] && newPresetName)
          {
            Options.customSlots[newPresetName] = [];
            preset = newPresetName;
          }
          else
          {
            preset = 0;
          }
        }

        if(preset == 0)
        {
          return;
        }
        
        if(isNumber(sourcePreset) && sourcePreset >= 1 && sourcePreset <= 8)
        {
          var sourcePresetList = Seed.throne.slotEquip[sourcePreset];
        }
        else
        {
          var sourcePresetList = Options.customSlots[sourcePreset];
        }
        
        if(isNumber(preset) && preset >= 1 && preset <= 8)
        {
          var copyList = [];
          
          for(i = 0 ; i < sourcePresetList.length ; i++)
          {
            copyList[i] = sourcePresetList[i];
          }
          
          Seed.throne.slotEquip[preset] = [];
          jQuery('#status').text("Copying to throne preset");

          setBusy(true);
          logit("Throne: [slot items 1] - " + JSON2.stringify(t.activeThroneSlotItems, null, 2));

          t.copyPreset(preset, copyList);
        }
        else
        {
          if(Options.customSlots[preset])
          {
            for(i = 0 ; i < sourcePresetList.length ; i++)
            {
              if(sourcePresetList[i])
              {
                var y = unsafeWindow.kocThroneItems[sourcePresetList[i]];
                var itemType = t.itemType[y.type];

                Options.customSlots[preset][itemType] = sourcePresetList[i];
              }
            }
          }
          saveOptions();
          t.Equip("Preset Copied");
        }
      });
      
      if(t.changePresetOnSelect && isNumber(t.activeThroneSlot) && t.activeThroneSlot <= Seed.throne.slotNum)
      {
        jQuery("#pbSourcePreset").val(Seed.throne.activeSlot);  
        t.activeThroneSlot = Seed.throne.activeSlot;
      }
      else
      {
        if(!t.activeThroneSlot)
        {
          t.activeThroneSlot = Seed.throne.activeSlot
        }
        jQuery("#pbSourcePreset").val(t.activeThroneSlot);
      }
      
      logit("Throne: [slot items 4] - " + JSON2.stringify(t.activeThroneSlotItems, null, 2));

      if(isNumber(t.activeThroneSlot) && t.activeThroneSlot >= 1 && t.activeThroneSlot <= 8)
      {
        var sourcePresetList = Seed.throne.slotEquip[t.activeThroneSlot];
      }
      else
      {
        var sourcePresetList = Options.customSlots[t.activeThroneSlot];
      }
      
      t.activeThroneSlotItems = sourcePresetList;
      
      t.FillEquipLists();
      
      logit("Throne: [slot items 5] - " + JSON2.stringify(t.activeThroneSlotItems, null, 2));

      stats = t.myThroneItemStats(t.activeThroneSlotItems);
      t.displayThroneStats(stats);
    } 
    catch (e) 
    {
      t.Overv.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }
  },

  populateSlotItemList : function()
  {
    var sourcePreset = jQuery("#pbSourcePreset").val()

    selectedSlot = parseIntWithDefault(sourcePreset, 0);
    
    if(selectedSlot >= 1 && selectedSlot <= 8)
    {
      t.activeThroneSlot = selectedSlot;
      t.activeThroneSlotItems = Seed.throne.slotEquip[selectedSlot];
      t.customPreset = false;
    }
    else
    {
      selectedSlot = sourcePreset;
      t.activeThroneSlot = selectedSlot;
      t.activeThroneSlotItems = Options.customSlots[selectedSlot];
      t.customPreset = true;
      t.fixPresetOrder(t.activeThroneSlotItems);
    }

    logit("Throne: [slot items 3] - ocs" + JSON2.stringify(Options.customSlots[selectedSlot], null, 2));
    logit("Throne: [slot items 3] - ats" + JSON2.stringify(t.activeThroneSlotItems, null, 2));
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fixPresetOrder : function(slotItems)
  {
    var t = Tabs.Throne;
    var tempItems = [];
    
    for(i = 0 ; i < slotItems.length ; i++)
    {
      tempItems.push(slotItems[i]);
      slotItems[i] = undefined;
    }
    
    for(i = 0 ; i < tempItems.length ; i ++)
    {
      if(unsafeWindow.kocThroneItems[tempItems[i]])
      {
        var y = unsafeWindow.kocThroneItems[tempItems[i]];
        
        var itemType = t.itemType[y.type];
        slotItems[itemType] = y.id;
      }
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addToPreset : function(preset, itemId)
  {
    var item = unsafeWindow.kocThroneItems[itemId];
    var itemType = item.type;
    
    if(Seed.throne.slotEquip[preset].indexOf(+itemId) != -1)
    {
      logit("Throne: items is not in the specified preset [" + preset + ", " + itemId + "]");
      return;
    }
    
    for(i = 0 ; i < Seed.throne.slotEquip[preset].length ; i ++)
    {
      var slotItem = unsafeWindow.kocThroneItems[Seed.throne.slotEquip[preset][i]];
      
      if(slotItem.type == item.type)
      {
        logit("Throne: removed " + item.type + " to add new item - " + itemId);
        Seed.throne.slotEquip[preset].splice(i,1);
        break;
      }
    }
    
    logit("Throne: Added item to preset [" + preset + ", " + itemId + "]");
    Seed.throne.slotEquip[preset].push(itemId);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  myThroneItemStats: function (activeSlotItems) 
  {
    var items = {};
    var stats;
   
    var slotNumber;
    
    for(i = 0 ; i < activeSlotItems.length ; i++)
    {
      if(activeSlotItems[i]) 
      {
        var item = unsafeWindow.kocThroneItems[activeSlotItems[i]];
        
        items[activeSlotItems[i]] = item;
      }
    }

    stats = getThroneStats(items); 

    return stats;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  displayThroneStats : function(throneStats)
  {
    var t = Tabs.Throne;
    
    var m = '';
    m += '<table class=trStatTab>';
    m += '<tr>';
    m += '<th>Boost</th><th>Value</th>';
    m += '</tr>';

    for(statId in throneStats)
    {
      var style='';
      
      boost = throneStats[statId];

      m += '<tr>';
      m += '<td>' + boost.name + '</td><td>' + boost.percent.toFixed(2) + '</td>';
      m += '</tr>';
    }

    m += '</table>';
    
    jQuery('#throneStats').html(m);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  copyPreset : function(preset, presetList) 
  {
    var t = Tabs.Throne;
    
    presetItem = presetList.shift();
    
    if(!presetItem || !unsafeWindow.kocThroneItems[presetItem])
    {
      if(presetList.length > 0)
      {
        setTimeout(function (){t.copyPreset(preset, presetList);}, 200);
        return;
      }
      else
      {
        t.populateSlotItemList();
        t.FillEquipLists();
        setBusy(false);
      }
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'equipItem';
    params.itemId = presetItem;
    params.presetId = preset;
    
    var failures = 0;
          
    _ajaxCall = function()
    {
      logit("Throne: Equip request - " + presetItem + ", " + preset);
      new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
        priority: true,
        
        onSuccess: function (transport) 
        {
          var rslt = eval("(" + transport.responseText + ")");
          
          if(rslt.ok)
          {
            Seed.throne.slotEquip[preset].unshift(params.itemId);
            
            logit("Throne: Equip request, success - " + JSON2.stringify(rslt, null, 2));
            if(presetList.length > 0)
            {
              setTimeout(function (){t.copyPreset(preset, presetList);}, 5000);
              return;
            }
            else
            {
              t.Equip("Finished Copy!");
              setBusy(false);
              return;
            }
          }
          else
          {
            logit("Throne: Equip request, failed - " + JSON2.stringify(rslt, null, 2));
            failures++;
            
            if(failures > 5)
            {
              t.Equip("Copy failed");
              setBusy(false);
              return;
            }
            
            setTimeout(function() {_ajaxCall();}, 5000);
          }
        },
        
        onFailure: function () 
        {
          logit("Throne: Equip request, failed");
          failures++;
          
          if(failures > 5)
          {
            t.Equip("Copy failed");
            setBusy(false);
            return;
          }
          
          setTimeout(function() {_ajaxCall();}, 5000);
        },
      });
    }
    
    _ajaxCall();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  togOpt : function (checkboxId, optionName, callOnChange)
  {
      var t = Tabs.Throne;
      var checkbox = document.getElementById(checkboxId);
      if (Options[optionName])
        checkbox.checked = true;
      checkbox.addEventListener ('change', eventHandler, false);
      function eventHandler (){
        Options[optionName] = this.checked;
        saveOptions();
        if (callOnChange)
          callOnChange (this.checked);
      }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  changeOpt : function (valueId, optionName, callOnChange)
  {
    var t = Tabs.Throne;
    var e = document.getElementById(valueId);
    e.value = Options[optionName];
    e.addEventListener ('change', eventHandler, false);
    
    function eventHandler ()
    {
      Options[optionName] = this.value;
      saveOptions();
      
      if (callOnChange)
        callOnChange (this.value);
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  togTrSaveOpt : function (checkboxId, item, boost, callOnChange)
  {
    var t = Tabs.Throne;
    var checkbox = document.getElementById(checkboxId);
    
    if (ThroneOptions.itemAttributes[item][boost].ignoreDebuff)
      checkbox.checked = true;
    
    checkbox.addEventListener ('change', eventHandler, false);
    
    function eventHandler ()
    {
      ThroneOptions.itemAttributes[item][boost].ignoreDebuff = this.checked;
      saveThroneOptions();
      if (callOnChange)
        callOnChange (this.checked);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  changeTrSaveOpt : function (valueId, item, boost, callOnChange){
      var t = Tabs.Throne;
      var e = document.getElementById(valueId);
      e.value = ThroneOptions.itemAttributes[item][boost].saveValue;
      e.addEventListener ('change', eventHandler, false);
      function eventHandler (){
        ThroneOptions.itemAttributes[item][boost].saveValue = this.value;
        saveThroneOptions();
        if (callOnChange)
          callOnChange (this.value);
      }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  toggleThroneState: function(){
    var t = Tabs.Throne;

    if (ThroneOptions.Active == true) {
      ThroneOptions.Active = false;
      document.getElementById('Enable').value = "Queue = OFF";
      saveThroneOptions();
      clearTimeout(t.setActionTimer);

      if (Seed.queue_throne.end == undefined) 
        document.getElementById('ShowStatus').innerHTML = "Auto Upgrade/Enhance/Repair is OFF.";
    } else {
      ThroneOptions.Active = true;
      document.getElementById('Enable').value = "Queue = ON";
      saveThroneOptions();
      t.setActionTimer = setInterval(t.doAction, 5 * 1000);
      document.getElementById('ShowStatus').innerHTML = "Waiting for timer ...";
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _addTab: function(id,name,qualityfrom,qualityto,levelfrom,levelto,action,active,cost)
  {
    var t = Tabs.Throne;
    var a="";
    var b=""; 

    switch (qualityfrom) 
    {
      case 0:a = unsafeWindow.g_js_strings.throneRoom.simple;break;
      case 1:a = unsafeWindow.g_js_strings.throneRoom.common;break;
      case 2:a = unsafeWindow.g_js_strings.throneRoom.uncommon;break;
       case 3:a = unsafeWindow.g_js_strings.throneRoom.rare;break;
      case 4:a = unsafeWindow.g_js_strings.throneRoom.epic;break;
      case 5:a = unsafeWindow.g_js_strings.throneRoom.wondrous;break;
      default:a = unsafeWindow.g_js_strings.throneRoom.simple;break;
    }

    switch (qualityto) 
    {
      case 0:b = unsafeWindow.g_js_strings.throneRoom.simple;break;
      case 1:b = unsafeWindow.g_js_strings.throneRoom.common;break;
      case 2:b = unsafeWindow.g_js_strings.throneRoom.uncommon;break;
      case 3:b = unsafeWindow.g_js_strings.throneRoom.rare;break;
      case 4:b = unsafeWindow.g_js_strings.throneRoom.epic;break;
      case 5:b = unsafeWindow.g_js_strings.throneRoom.wondrous;break;
      default:b = unsafeWindow.g_js_strings.throneRoom.simple;break;
    }

    var row = document.getElementById('ShowQueue').insertRow(0);
    row.vAlign = 'top';
    row.style.color = "black";  
    row.style.background = "rgb(246,243,236)";

    if (active) 
    {
      row.style.color = "green";   
    }
    
    row.insertCell(0).innerHTML = id+1;
    row.insertCell(1).innerHTML = name;

    if (action == "Enhance") 
    {
      row.insertCell(2).innerHTML = a + " -> " + b;
      row.insertCell(3).innerHTML = levelfrom;
    }

    if (action == "Upgrade") 
    {
      row.insertCell(2).innerHTML = a;
      row.insertCell(3).innerHTML = levelfrom + " -> " + levelto;
    }

    row.insertCell(4).innerHTML = action;
    row.insertCell(5).innerHTML = cost;
    row.insertCell(6).innerHTML = '<a class="button20" id="queueDelete_' + id + '"><span>Delete</span></a>';

    document.getElementById('queueDelete_' + id).addEventListener('click', function()
    {
      if (ThroneOptions.Items[id].active ==true) 
      {
        ThroneOptions.Tries = 0;
      }
      
      if (ThroneOptions.Items.length ==0 && ThroneOptions.Active) 
      {
        jQuery('#ShowStatus').html("No items in queue!!");
      }
      
      if (!ThroneOptions.Active) 
      {
        jQuery('#ShowStatus').html("Auto Upgrade/Enhance/Repair is OFF.");
      }
      
      ThroneOptions.Items.splice (id,1);
      saveThroneOptions();
      t.checkUpgradeInfo(false);
      t.PaintQueue();

      if (ThroneOptions.Items.length > 0) 
      {
        t.paintInfo();
      } 
      else 
      {
        jQuery('#ShowInfo').html("");
      }
    }, false);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _addTabHeader: function() 
  {
    var t = Tabs.Throne;
    var row = document.getElementById('ShowQueue').insertRow(0);
    row.vAlign = 'top';
    row.style.color = "black";
    row.style.background = "rgb(246,243,236)";
    row.insertCell(0).innerHTML = "Id";
    row.insertCell(1).innerHTML = "Name";
    row.insertCell(2).innerHTML = "Quality";
    row.insertCell(3).innerHTML = "Level";
    row.insertCell(4).innerHTML = "Action";
    row.insertCell(5).innerHTML = "Cost";
    row.insertCell(6).innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  FillEquipLists: function()
  {
    var t = Tabs.Throne;
    
    logit("Throne: [slot items 2] - " + JSON2.stringify(t.activeThroneSlotItems, null, 2));
    
    for (k in t.ItemTypeList) 
    {
      var y = t.ItemTypeList[k];
      var itemEquiped = 0;
      var count = 0;
      
      if (typeof(y) == "string") 
      {
        what = y.toLowerCase();
        
        document.getElementById(what).options.length = 0;
        
        for (l in unsafeWindow.kocThroneItems) 
        {
          z = unsafeWindow.kocThroneItems[l];
          check = what;
          
          if (check == "windows")
          {
            check = "window";
          }
          count++;
          
          if (count <= (parseInt(Seed.throne.rowNum) * 5))
          {
            if (z.type == check) 
            { 
              var o = document.createElement("option");     
              o.text = z.name;
              o.value = l;
              document.getElementById(what).options.add(o);
              
              if(t.activeThroneSlotItems.indexOf(z.id) != -1)
              {
                itemEquiped = l;
              }
            }
          } 
        }
        
        if (document.getElementById(what).options.length == 0)
        {
          var o = document.createElement("option"); 
          o.text = "No " + check + " item available :(";
          o.value = 1;
          document.getElementById(what).options.add(o);
          itemEquiped = 1;
        } 
        else if (itemEquiped == 0) 
        {
          var o = document.createElement("option");     
          o.text = "No " + check + " item equiped !!!";
          o.value = 2;
          document.getElementById(what).options.add(o);
          document.getElementById('info' + what).innerHTML = "";
          itemEquiped = 2;
        }
        
        logit('Throne: [show equip] - ' + what + ' / ' + itemEquiped);
        document.getElementById(what).value = itemEquiped;  
      }
      
      switch(itemEquiped)
      {
        case 0:
          break;
        
        case 1: 
          document.getElementById("Equip" + what).disabled = true;
          document.getElementById("Unequip" + what).disabled = true;
          break;
        
        case 2:
          document.getElementById("Equip" + what).disabled = false;
          document.getElementById("Unequip" + what).disabled = true;
          break;
        
        default:
          document.getElementById("Equip" + what).disabled = true;
          document.getElementById("Unequip" + what).disabled = false;
          t.paintEquipItemInfo(document.getElementById(what).value,what);
          break;
      }
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doPreset : function (preset)
  {
    var t = Tabs.Throne;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'setPreset';
    params.presetId = preset;
        
    logit("Preset swap request");
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      onSuccess: function (transport) {
        var rslt = eval("(" + transport.responseText + ")");
          if(rslt.ok){
            button = '<li id="throneInventoryPreset' + preset + '" class="active">'+preset+'</li>';
            CM.ThroneView.clickActivePreset(button);
            CM.ThroneView.renderThrone();
            CM.ThroneView.renderStats();
            setPresetWidget(preset);

            t.Equip("Changed Preset");
            Seed.throne.activeSlot = preset;
           } 
      },
      onFailure: function () {
         return;
      },
    });
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintEquipItemInfo : function (z,what){
    var t = Tabs.Throne;
    var m="";

    if (typeof(unsafeWindow.kocThroneItems[z]) == 'object') {
        var y = unsafeWindow.kocThroneItems[z];
    } else {
      return;
    }

    var id =0;
    var tier=0;
    var Current=0;
    m="<TABLE width=100% height=0% class=pbTab>";

    for (i=1;i<=5;i++) {
      id = y["effects"]["slot"+i]["id"];
      tier = parseInt(y["effects"]["slot"+i]["tier"]);
      level = y["level"];
      p = CM.thronestats.tiers[id][tier];
      Current = p.base + ((level * level + level) * p.growth * 0.5);
      var quality = parseInt(y["quality"]);
      
      if (i<=quality) {
        m+='<TR><TD><FONT color=green>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
      } else {
        m+='<TR><TD><FONT color=red>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
      }
    }
    
    m+="</table>"

    document.getElementById('info'+what).innerHTML = m;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  PaintHistory : function() {
    var t = Tabs.Throne;
    var popHistory = null;
    popHistory = new pbPopup('pbShowHistory', 0, 0, 1100, 500, true, function() {clearTimeout (1000);});
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbShowBarbs" id="pbBars">';       
    popHistory.getMainDiv().innerHTML = '</table></div>' + m;
    popHistory.getTopDiv().innerHTML = '<TD><B>Succesfull Upgrade/Enhance list:</td>';

    for (i=0;i<t.log.length;i++){
      var row = document.getElementById('pbBars').insertRow(0);
      row.vAlign = 'top';
      row.style.color = "black";
      row.insertCell(0).innerHTML = t.log[i].time;
      row.insertCell(1).innerHTML = t.log[i].name;
      row.insertCell(2).innerHTML = t.log[i].action;
      row.insertCell(3).innerHTML = t.log[i].tries;
      row.insertCell(4).innerHTML = t.log[i].good;
      row.insertCell(5).innerHTML = t.log[i].bad;
    }

    var row = document.getElementById('pbBars').insertRow(0);
    row.vAlign = 'top';
    row.style.color = "black";
    row.insertCell(0).innerHTML = "Time";
    row.insertCell(1).innerHTML = "Name";
    row.insertCell(2).innerHTML = "Action";
    row.insertCell(3).innerHTML = "Tries";
    row.insertCell(4).innerHTML = "Good Req.";
    row.insertCell(5).innerHTML = "Bad Req.";
    popHistory.show(true) ;
  },


  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  PaintSalvageHistory : function() 
  {
    var t = Tabs.Throne;
    var popHistory = null;
    popHistory = new pbPopup('pbSalvageShowHistory', 0, 0, 1100, 500, true, function() {clearTimeout (1000);});
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbShowBarbs" id="pbBars">';       
    popHistory.getMainDiv().innerHTML = '</table></div>' + m;
    popHistory.getTopDiv().innerHTML = '<TD><B>Throne room Salvage list:</td>';
    
    for (i=0;i<t.SalvageLog.length;i++)
    {
      var row = document.getElementById('pbBars').insertRow(0);
      row.vAlign = 'top';
      row.style.color = "black";
      row.insertCell(0).innerHTML = t.SalvageLog[i].time;
      row.insertCell(1).innerHTML = t.SalvageLog[i].stones;
      row.insertCell(2).innerHTML = t.SalvageLog[i].msg;
      
      if(t.SalvageLog[i].bonus) 
        row.insertCell(3).innerHTML = t.SalvageLog[i].bonus;
      else
        row.insertCell(3).innerHTML = "";
    }
    
    var row = document.getElementById('pbBars').insertRow(0);
    row.vAlign = 'top';
    row.style.color = "black";
    row.insertCell(0).innerHTML = "Time";
    row.insertCell(1).innerHTML = "Aetherstones";
    row.insertCell(2).innerHTML = "Action";
    row.insertCell(3).innerHTML = "Bonus";
    
    popHistory.show(true) ;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addToQueue : function (id, action)
  {
    var t= Tabs.Throne;

    document.getElementById('ShowHoover').innerHTML = "";
    ThroneOptions.Items.push ({id:id,action:action,name:unsafeWindow.kocThroneItems[id]["name"],qualityfrom:0,qualityto:0,levelfrom:0,levelto:0,cost:0,active:false});
    saveThroneOptions();
    t.checkUpgradeInfo(false);
    t.PaintQueue();
    t.paintInfo();

    if (ThroneOptions.Active) 
    {
      document.getElementById('ShowStatus').innerHTML = "Starting Next Queue item..."
    } 
    else 
    {
      document.getElementById('ShowStatus').innerHTML = "Auto Upgrade/Enhance/Repair is OFF."; 
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  autoAddUpgrades: function(id)
  {
    var t = Tabs.Throne;
    var item;
    
    if(unsafeWindow.kocThroneItems[id])
    {
        item = unsafeWindow.kocThroneItems[id];
    }
    else
    {
        return;
    }
    
    // now add on the amount of enhamces required to reach wonderous
    var quality = item.quality;
    
    while(quality < 5)
    {
        ThroneOptions.Items.push ({id:id,action:"Enhance",name:unsafeWindow.kocThroneItems[id]["name"],qualityfrom:0,qualityto:0,levelfrom:0,levelto:0,cost:0,active:false});
        quality++;
    }
    
    var level = item.level;
    while(level < 5)
    {
        ThroneOptions.Items.push ({id:id,action:"Upgrade",name:unsafeWindow.kocThroneItems[id]["name"],qualityfrom:0,qualityto:0,levelfrom:0,levelto:0,cost:0,active:false});
        level++;
    }
    
    t.checkUpgradeInfo(false);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  autoUpgradeTokens: function(id, failed)
  {
    var t = Tabs.Throne;
    
    if(t.autoUpgradeStop)
    {
      t.autoUpgradeStop = false;
      t.autoUpgradeMessage = "Manual stop requested";
      if(failed)
      {
        t.upgradeStatusFunction("failure");
      }
      return;
    }
    
    if(Seed.items["i20005"] <= Options.autoTrUpgradeLeaveTokens)
    {
      logit("Throne: Used maximum tokens set");
      t.autoUpgradeMessage = "Used maximum tokens allowed based on settings, or no tokens remaining";

      if(failed)
      {
        t.upgradeStatusFunction("failure");
      }
      return;
    }

    var cityid = 0;
    var maxAmount = 0;

    if(Options.autoItemUpgradeMaxTokens != 0 && t.autoUpgradeTries >= Options.autoItemUpgradeMaxTokens)
    {
      logit("Throne: Token limit reach for auto-upgrade!");
      t.autoUpgradeMessage = "Used maximum tokens allowed based on settings, or no tokens remaining";
      
      if(failed)
      {
        t.upgradeStatusFunction("failure");
      }
      
      return;
    }
    
    for (var k in Cities.byID) 
    {
      if(Seed.resources["city"+k]["rec5"][0] > Options.autoItemUpgradeSaveAmount) 
      {
        if(Seed.resources["city"+k]["rec5"][0] > maxAmount)
        {
          cityid = k;
          maxAmount = Seed.resources["city"+k]["rec5"][0];
        }
      }
    }
    
    if (cityid == 0) 
    {
      logit("Throne: Not enough astone to use token upgrade!");
      t.autoUpgradeMessage = "We have reached the astone usage limit";
      
      if(failed)
      {
        t.upgradeStatusFunction("failure");
      }
      
      return;
    } 
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = "throneRoom\\ThroneRoomServiceAjax";
    params.action = "upgradeLevel";
    params.throneRoomItemId = id;
    params.payment = "aetherstone";
    params.buffItemId = 20005;
    params.cityId = cityid;
    
    logit("Throne: Auto Upgrade Attempt");
    
    t.autoUpgradeTries++;

    new PriorityAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        var item = uW.kocThroneItems[id];
       
        Options.autoTokenTries[id]++;
        saveOptions();

        logit("Throne: Auto upgrade attempt completed");
     
        Seed.resources["city" + cityid]["rec5"][0] = Seed.resources["city" + cityid]["rec5"][0] - rslt.aetherstones;
        Seed.items["i20005"]--;
        
        if(rslt.gems > 0)
        {
          logit("Throne: Damn token update spent gems!!");
          return;
        }
        
        if(rslt.success)
        {
          upgradeStats.upgradeSuccess[item.quality][item.level]++;
          item.quality = rslt.item.quality;
          item.level = rslt.item.level;
          item.name = item.createName();
          logit("Throne: Auto upgrade tokens [success]");
          t.upgradeStatusFunction("success");
          delete Options.autoTokenTries[id];
          t.addToLog(id, "Upgrade (Tokens)", t.autoUpgradeTries ,0, 0);
          t.autoUpgradeMessage = "Item upgraded: Now level +" + rslt.item.level;
        }
        else
        {
          upgradeStats.upgradeFailure[item.quality][item.level]++;
          logit("Throne: Auto upgrade tokens [failure]");
          failed = true;
          setTimeout(function() {t.autoUpgradeTokens(id, failed);}, 1 * 1000);
        }
        
        CM.ThroneView.renderInventory(uW.kocThroneItems);
        CM.HeatUpModel.attemptCallback(+(rslt.heatupModifier))
      },
      
      onFailure: function () 
      {
        logit("Throne: Auto upgrade tokens [failure (onFailure)]");
      },
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkUpgradeInfo : function (firstRun)
  {
    var t= Tabs.Throne;
    var countUpgrade = 0;
    var countEnhance = 0;
    var levelfrom = 0;
    var levelto =0;
    var qualityfrom = 0;
    var qualityto = 0;
    
    if (ThroneOptions.Items.length == 0) 
    {
      return;
    }
    
    for (k = 0 ; k < ThroneOptions.Items.length ; k++)
    {
      countUpgrade = 0;
      countEnhance = 0;

      if (unsafeWindow.kocThroneItems[ThroneOptions.Items[k]["id"]] != undefined) 
      {
        if (k > 0) 
        {
          for (l = 0 ; l < k ; l++) 
          {
            if (ThroneOptions.Items[l]["id"] == ThroneOptions.Items[k]["id"] && ThroneOptions.Items[l]["action"] == "Upgrade") 
            {
              countUpgrade++;
            }

            if (ThroneOptions.Items[l]["id"] == ThroneOptions.Items[k]["id"] && ThroneOptions.Items[l]["action"] == "Enhance") 
            {
              countEnhance++;
            }
          }
        }
        
        if (ThroneOptions.Items[k]["action"] == "Upgrade") 
        {
          ThroneOptions.Items[k]["levelfrom"] = parseInt(unsafeWindow.kocThroneItems[ThroneOptions.Items[k]["id"]]["level"]) + countUpgrade;
          ThroneOptions.Items[k]["levelto"] = parseInt(ThroneOptions.Items[k]["levelfrom"]) +1;
          ThroneOptions.Items[k]["qualityfrom"] = parseInt(unsafeWindow.kocThroneItems[ThroneOptions.Items[k]["id"]]["quality"]) + countEnhance;
          
          if (ThroneOptions.Items[k]["levelto"] > 10 && !firstRun) 
          {
            //alert("You can't upgrade higher then level 10!");
            ThroneOptions.Items.splice (k,1);
            return;
          }
        }

        if (ThroneOptions.Items[k]["action"] == "Enhance") 
        {
          ThroneOptions.Items[k]["qualityfrom"] = parseInt(unsafeWindow.kocThroneItems[ThroneOptions.Items[k]["id"]]["quality"]) + countEnhance;
          ThroneOptions.Items[k]["qualityto"] = parseInt(ThroneOptions.Items[k]["qualityfrom"]) +1;
          ThroneOptions.Items[k]["levelfrom"] = parseInt(unsafeWindow.kocThroneItems[ThroneOptions.Items[k]["id"]]["level"]) + countUpgrade;

          if (ThroneOptions.Items[k]["qualityto"] > 5 && !firstRun) 
          {
            //alert("You can't upgrade higher then quality 5!");
            ThroneOptions.Items.splice (k,1);
            return;
          }
        }

        if (ThroneOptions.Items[k]["action"] == "Enhance") 
        {
          var lvl = parseInt(ThroneOptions.Items[k]["qualityfrom"]) +1;
        }
        
        if (ThroneOptions.Items[k]["action"] == "Upgrade") 
        {
          var lvl = parseInt(ThroneOptions.Items[k]["levelfrom"]) +1;
        }
        
        costAction = ThroneOptions.Items[k]["action"].toLowerCase();

        if (CM.thronestats[costAction][lvl] != undefined) 
        {
          ThroneOptions.Items[k]["cost"] = CM.thronestats[costAction][lvl].Stones;
        } 
        else 
        {
          ThroneOptions.Items.splice (k,1);
        }
      } 
      else 
      {
        ThroneOptions.Items.splice (k,1);
      }
    }
    
    saveThroneOptions();
  },
    
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  PaintQueue : function ()
  {
    var t= Tabs.Throne;
    
    if(document.getElementById('ShowQueueDiv'))
    {
      document.getElementById('ShowQueueDiv').innerHTML = '<TABLE id=ShowQueue class=pbStat align="center" width=90%></table>';

      for (k = (ThroneOptions.Items.length-1) ; k >= 0 ; k--)
      {
        if (typeof(unsafeWindow.kocThroneItems[ThroneOptions.Items[k]["id"]]) == 'object') 
        {
          t._addTab(k,ThroneOptions.Items[k]["name"],ThroneOptions.Items[k]["qualityfrom"],ThroneOptions.Items[k]["qualityto"],ThroneOptions.Items[k]["levelfrom"],ThroneOptions.Items[k]["levelto"],ThroneOptions.Items[k]["action"],ThroneOptions.Items[k]["active"],ThroneOptions.Items[k]["cost"]);
        }
        else
        {
          ThroneOptions.Items.splice (k,1);
        }
      }

      t._addTabHeader();
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doAction : function (){
    var t= Tabs.Throne;
    var status;

    if (!ThroneOptions.Active) return;
    
    if (ThroneOptions.Items.length ==0) {
      status = "No items in queue!!";
    } else {
      ThroneOptions.Items["0"]["active"] = true;
      t.PaintQueue();

      if(t.throneBusy)
        return;
        
      if (unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].isBroken == true && Seed.queue_throne.end == undefined) {
        status = "Waiting to repair ...";
        unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].isBroken = false;
        unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].brokenType = "";
        
        t.doRepair();
        
      } else if (unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].isBroken == false && Seed.queue_throne.end == undefined) {
        status = "Waiting to " + ThroneOptions.Items["0"]["action"] + "...";
        
        if (ThroneOptions.Items["0"]["action"] == "Upgrade") 
          t.doUpgrade();
        
        if (ThroneOptions.Items["0"]["action"] == "Enhance") 
          t.doEnhance();
      }
    }
    
    if(status)
      if(document.getElementById('ShowStatus')) 
        document.getElementById('ShowStatus').innerHTML = status;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doEnhance : function() 
  {
    var t = Tabs.Throne;
    var cityid = t.highestAstoneCity();
    
    if (typeof(unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]]) == 'object') 
    {
      var y = unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]];
    } 
    else 
    {
      return;
    }
    
    if ( Seed.resources["city" + cityid]["rec5"][0] < parseInt((ThroneOptions.Items["0"]["cost"])))
    {
      jQuery('ShowStatus').text("Not enough aetherstone to enhance!!");
      return; 
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'upgradeQuality';
    params.throneRoomItemId = ThroneOptions.Items["0"]["id"];
    params.buffItemId = 0;
    params.payment = "aetherstone";
    params.cityId = cityid;
    
    logit("Enhance request");
    
    t.throneBusy = true;
    
    new PriorityAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        if(rslt.ok) 
        {
          if (rslt.gems > 0) 
          {
            jQuery('ShowStatus').text('Upgrader accidentally spent gems!  Turning upgrader off!!');
            ThroneOptions.Active = false;
            saveThroneData();
          }
          
          Seed.resources["city" + cityid]["rec5"][0] -= rslt.aetherstones;
          
          if (rslt.success)
          {         
            upgradeStats.enhanceSuccess[y.quality][y.level]++;
            y.level = rslt.item.level;
            y.quality = rslt.item.quality
            y.status = rslt.item.status;
            y.name = y.createName();
            saveUpgradeStats();
            t.addToLog(ThroneOptions.Items["0"]["id"],ThroneOptions.Items["0"]["action"],ThroneOptions.Tries,ThroneOptions.Good,ThroneOptions.Bad);
            ThroneOptions.Tries = 0;
            ThroneOptions.Good = 0;
            ThroneOptions.Bad = 0;
            saveThroneOptions();
            jQuery('ShowTries').html("Tries: --");
            
            ThroneOptions.Items.splice (0,1);
          } 
          else 
          {
            y.isBroken = true;
            y.brokenType = "quality";
            upgradeStats.enhanceFailure[y.quality][y.level]++;
            y.level = rslt.item.level;
            y.quality = rslt.item.quality
            y.status = rslt.item.status;
            y.name = y.createName();
            saveUpgradeStats();
            ThroneOptions.Tries++;
            jQuery('ShowStatus').html('Enhance failed <br />Item: ' + unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].name +"<br />Waiting for repair...");
            jQuery('ShowTries').html("Tries: " + ThroneOptions.Tries);
          }
          
          CM.ThroneView.renderInventory(unsafeWindow.kocThroneItems);
          
          t.checkUpgradeInfo(false);
          t.PaintQueue();
          ThroneOptions.Good++;
          saveThroneOptions();
        } 
        else 
        {
          ThroneOptions.Bad++;
          saveThroneOptions();
        }
        t.throneBusy = false;

        return; 
      },
      
      onFailure: function () 
      {
        t.throneBusy = false;

        return;
      },
    });
  },
     
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doUpgrade : function() 
  {
    var t = Tabs.Throne;
    var cityid = t.highestAstoneCity();
    
    if (typeof(unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]]) == 'object') 
    {
      var y = unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]];
    } 
    else 
    {
      return;
    }

    if ( Seed.resources["city" + cityid]["rec5"][0] < parseInt((ThroneOptions.Items["0"]["cost"])))
    {
      jQuery('ShowStatus').text("Not enough aetherstone to enhance!!");
      return; 
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'upgradeLevel';
    params.throneRoomItemId = ThroneOptions.Items["0"]["id"];
    params.buffItemId = 0;
    params.payment = "aetherstone";
    params.cityId = cityid;
    logit("Throne: Upgrade request");
    
    t.throneBusy = true;

    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      priority: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        var status;
        
        if(rslt.ok)
        {
          if (rslt.gems > 0)
          {
            status = 'Upgrader accidentally spent gems!  Turning upgrader off!!';
            ThroneOptions.Active = false;
            saveThroneData();
          }

          Seed.resources["city" +cityid]["rec5"][0] -= rslt.aetherstones;

          if (rslt.success)
          {
            upgradeStats.upgradeSuccess[y.quality][y.level]++;
            y.level = rslt.item.level;
            y.quality = rslt.item.quality;
            y.status = rslt.item.status;
            y.name = y.createName();
            saveUpgradeStats();
            t.addToLog(ThroneOptions.Items["0"]["id"],ThroneOptions.Items["0"]["action"],ThroneOptions.Tries,ThroneOptions.Good,ThroneOptions.Bad);
            ThroneOptions.Tries = 0;
            ThroneOptions.Good = 0;
            ThroneOptions.Bad = 0;
            saveThroneOptions();
            jQuery('ShowTries').text("Tries: --");
            ThroneOptions.Items.splice (0,1);
          }
          else
          {
            y.isBroken = true;
            y.brokenType = "level";
            upgradeStats.upgradeFailure[y.quality][y.level]++;
            y.level = rslt.item.level;
            y.quality = rslt.item.quality;
            y.status = rslt.item.status;
            y.name = y.createName();
            saveUpgradeStats();
            ThroneOptions.Tries++;
            saveThroneOptions();
            status = 'Upgrade failed <br />Item: ' + unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].name +"<br />Waiting for repair ...";
            jQuery('ShowTries').text("Tries: " + ThroneOptions.Tries);
          }
          CM.ThroneView.renderInventory(unsafeWindow.kocThroneItems);
        
          t.checkUpgradeInfo(false);
          t.PaintQueue();
          ThroneOptions.Good++;
          saveThroneOptions();
          jQuery('#ShowStatus').text(status);
        } 
        else 
        {
          ThroneOptions.Bad++;
          saveThroneOptions();
        }
        
        t.throneBusy = false;

        return;
      },
      
      onFailure: function () 
      {
        t.throneBusy = false;

        return;
      },
    });   
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doRepair : function() 
  {
    var t = Tabs.Throne;
    var cityid = 0;
    for (var k in Cities.byID) {
      if ( Seed.resources["city"+k]["rec5"][0] > ThroneOptions.minStones)
      {
         cityid = k;
      }
    }

    if(cityid == 0)
    {
      if(document.getElementById('ShowStatus')) document.getElementById('ShowStatus').innerHTML = "Not enough aetherstone to enhance";
      return; 
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'timeRepair';
    params.throneRoomItemId = ThroneOptions.Items["0"]["id"];
    params.cityId = cityid;
          
    logit("Throne: Repair request");
    t.throneBusy = true;

    new PriorityAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        
        if(rslt.ok)
        {
          ThroneOptions.RepairEnd = rslt.eta; 
          var now = new Date().getTime()/1000.0;
          t.setRepairTimer = setInterval (t.repairTimerUpdate,1000); 
          Seed.queue_throne.itemId= ThroneOptions.Items["0"]["id"];
          Seed.queue_throne.start=unixTime();
          Seed.queue_throne.end= rslt.eta;
          t.repairId = ThroneOptions.Items["0"]["id"];
          t.repairEnd = rslt.eta;
          CM.ThroneView.renderInventory(unsafeWindow.kocThroneItems);
          var x = rslt.eta - unixTime();
          ThroneOptions.Good++;
          saveThroneOptions();
        } 
        else 
        { 
          ThroneOptions.Good++;
          saveThroneOptions();
        }   
        
        t.throneBusy = false;

        return;
      },

      onFailure: function () 
      {
        t.throneBusy = false;

        return;
      },
    });
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doEquip : function(n, preset) 
  {
    var t = Tabs.Throne;
    
    if (typeof(unsafeWindow.kocThroneItems[n]) == 'object') 
    {
      var y = unsafeWindow.kocThroneItems[n];
    } 
    else 
    {
      return;
    }

    if(t.customPreset)
    {
      var itemType = t.itemType[y.type];
      t.activeThroneSlotItems[itemType] = y.id;
      t.FillEquipLists();
      saveOptions();
    
      stats = t.myThroneItemStats(t.activeThroneSlotItems);
      t.displayThroneStats(stats);
    
      return;
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'equipItem';
    params.itemId = y.id;
    params.presetId = t.activeThroneSlot;
          
    setBusy(true);

    logit("Throne: Equip request");
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      priority: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        
        if(rslt.ok)
        {
          setBusy(false);
          
          if(params.presetId == Seed.throne.activeSlot)
          {
            CM.ThroneView.clickItemEquip(y);
          }
          
          t.addToPreset(params.presetId, params.itemId);
          t.Equip("Item Equipped");
        } 
      },
      
      onFailure: function () 
      {
        setBusy(false);
        return;
      },
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doUnequip : function(n,preset) 
  {
    var t = Tabs.Throne;
    if (typeof(unsafeWindow.kocThroneItems[n]) == 'object') 
    {
      var y = unsafeWindow.kocThroneItems[n];
    } 
    else 
    {
      return;
    }

    if(t.customPreset)
    {
      var itemType = t.itemType[y.type];
      t.activeThroneSlotItems[itemType] = undefined;
      saveOptions();
      t.FillEquipCheckboxes();

      stats = t.myThroneItemStats(t.activeThroneSlotItems);
      t.displayThroneStats(stats);

      return;
    }

    setBusy(true);
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'unequipItem';
    params.itemId = y.id;
    params.presetId = t.activeThroneSlot;
          
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      priority: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        
        if(rslt.ok)
        {
          CM.ThroneView.clickItemUnequip(y);
          var itemIndex = Seed.throne.slotEquip[+params.presetId].indexOf(+params.itemId);
          
          if(itemIndex != -1)
          {
            Seed.throne.slotEquip[+params.presetId].splice(itemIndex, 1);
          }

          t.Equip("Item Un-equipped");
          setBusy(false);
        } 
      },
      
      onFailure: function () 
      {
        setBusy(false);
        return;
      },
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  isQueued : function(id)
  {
    var queued = false;
    
    for (i = 0 ; i < ThroneOptions.Items.length ; i++)
    {
      if(id == ThroneOptions.Items[i].id)
      {
        queued = true;
        break;
      }
    }
    
    return queued;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateElement : function(element,value) 
  {
    if(document.getElementById(element))
    {
      document.getElementById(element).innerHTML = value;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  repairTimerUpdate :function (){
    var t = Tabs.Throne;
    
    if (ThroneOptions.Items.length == 0) 
    {
      return;
    }

    var now = new Date().getTime()/1000.0;
    var diff = 0;
    var status;
    
    if (Seed.queue_throne.end == undefined) 
    {
      return;
    }
    else 
    {
      diff = Seed.queue_throne.end - now;
    }

    if (diff < 0)
    {
      clearTimeout(t.setRepairTimer);
      if (ThroneOptions.Active) 
      {
        status = "Waiting for timer...";
      }
      else 
      {
        status = "Auto Upgrade/Enhance/Repair is OFF."; 
      }
      
      unsafeWindow.kocThroneItems[Seed.queue_throne.itemId].isBroken = false;
      Seed.queue_throne = "";
    } 
    else 
    {
      status = "Repairing on: " + unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]].name + "<br/>Time left: " + timestr(diff)+ " ("+ timestr(Seed.queue_throne.end - Seed.queue_throne.start) + ")";
      jQuery('#ShowTries').html("Tries: " + ThroneOptions.Tries);
    }
  
    jQuery('#ShowStatus').html(status);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintInfo : function ()
  {
    var t = Tabs.Throne;
    if(!document.getElementById('ShowInfo'))
    {
      return;
    }

    if (unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]]) {
        var y = unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]];
    } else return;
    
    var id =0;
    var tier=0;
    var Current=0;
    var Next=0;
    m="<TABLE width=80% height=0% align='center' class=pbTab><TR><TD><B>Current</b></td><TD><B>Next</b></td>";

    for (i=1;i<=5;i++) {
      id = y["effects"]["slot"+i]["id"];
      tier = parseInt(y["effects"]["slot"+i]["tier"]);
      level = y["level"];
      p = CM.thronestats.tiers[id][tier];
      Current = p.base + ((level * level + level) * p.growth * 0.5);
      level++;
      Next = p.base + ((level * level + level) * p.growth * 0.5);

      var quality = parseInt(unsafeWindow.kocThroneItems[ThroneOptions.Items["0"]["id"]]["quality"]);

      if (ThroneOptions.Items["0"]["action"] == "Enhance") {
        if (i<=quality) 
          m+='<TR><TD><FONT color=green>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td>';
        else 
          m+='<TR><TD><FONT color=red>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td>';

        if (i<=(quality+1)) 
          m+='<TD><FONT color=green>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
        else 
          m+='<TD><FONT color=red>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
      }

      if (ThroneOptions.Items["0"]["action"] == "Upgrade") {
        if (i<=quality) {
          m+='<TR><TD><FONT color=green>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td>';
        } else { 
          m+='<TR><TD><FONT color=red>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td>';
        }
        
        if (i<=quality) { 
          m+='<TD><FONT color=green>' + Next.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
        } else {
          m+='<TD><FONT color=red>' + Next.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
        }
      } 
    }
    m+="</table>"
    document.getElementById('ShowInfo').innerHTML = m;  

  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintHoover : function (){
    var t = Tabs.Throne;
    var z = document.getElementById('ThroneItems').value;
      var y = unsafeWindow.kocThroneItems[z];
    var id =0;
    var tier=0;
    var Current=0;
    
    logit("Display boosts for selected item");
    //logit(JSON2.stringify(y,null,2));
    
    m="<TABLE width=80% height=0% align='center' class=pbTab>";
    for (i=1;i<=5;i++) {
      id = y["effects"]["slot"+i]["id"];
      tier = parseInt(y["effects"]["slot"+i]["tier"]);
      level = y["level"];
      p = CM.thronestats.tiers[id][tier];
      Current = p.base + ((level * level + level) * p.growth * 0.5);
      var quality = parseInt(y["quality"]);
      if (i<=quality) m+='<TR><TD><FONT color=green>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
      else m+='<TR><TD><FONT color=red>' + Current.toFixed(2) + "% " + CM.thronestats["effects"][id]["1"] + '</font></td></tr>';
    }
    m+="</table>"
    document.getElementById('ShowHoover').innerHTML = m;  

  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintStones : function ()
  {
    var t = Tabs.Throne;
    
    m="<TABLE width=90% height=0% class=pbTab><TR><TD>Aetherstones: </td>";
    
    for (i = 0 ; i < Seed.cities.length ; i++) 
      m+='<TD>' + Seed.cities[i]["1"] + '</td>';
    
    m+="</tr><TR><TD></td>"
    
    for (i = 0 ; i < Seed.cities.length ; i++) 
      m+='<TD>' + addCommas(Seed.resources["city" + Seed.cities[i]["0"]]["rec5"][0]) + '</td>';
    
    m+="</tr></table>"
    
    jQuery('#ShowStones').html(m);  
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addToLog : function (id, action, tries, good, bad)
  {
    var t = Tabs.Throne;
    var now = new Date();

    D = t.addZero(now.getDate());
    M = t.addZero(now.getMonth() + 1);
    Y = t.addZero(now.getFullYear());
    h = t.addZero(now.getHours());
    m = t.addZero(now.getMinutes()); 
    
    var time =  D +"/"+ M +"/"+ Y +"  "+ h + ":" + m;
    
    var name = unsafeWindow.kocThroneItems[id]["name"];

    t.log.push ({time:time, name:name, action:action, tries:tries, good:good, bad:bad});

    if (t.log.length > 500) 
    {
      t.log.splice(0,1);
    }

    GM_setValue ('ThroneHistory_'+getServerId(), JSON2.stringify(t.log));
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addToSalvageLog : function (msg, stones, bonus) 
  {
    var t = Tabs.Throne;
    var now = new Date();
    
    D = t.addZero(now.getDate());
    M = t.addZero(now.getMonth() + 1);
    Y = t.addZero(now.getFullYear());
    h = t.addZero(now.getHours());
    m = t.addZero(now.getMinutes()); 
    
    var time =  D +"/"+ M +"/"+ Y +"  "+ h + ":" + m;
    
    t.SalvageLog.push ( {time:time, stones:stones, msg:msg, bonus:bonus} );
    
    if (t.SalvageLog.length > 500) 
    {
      t.SalvageLog.splice(0,1);
    }
    
    GM_setValue ('ThroneSalvageHistory_'+getServerId(), JSON2.stringify(t.SalvageLog));
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addZero : function (i)
  {
    if (i < 10) 
    {
      i = "0" + i;
    }
    
    return i;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  salvageCheck : function ()
  {
    var t = Tabs.Throne;
    var del = false; //false by default
    var level = false;
    var type ="";
    var NotUpgrading = true;
    var count=0;
    var saveCount = 0;
    var itemCount = 0;
    var boostDelete = false;

    if(Options.ThroneDeleteItems && t.SalvageRunning == false) 
    {
      t.SalvageRunning = true;

      for (m in unsafeWindow.kocThroneItems) 
      {
        itemCount++;
        y = unsafeWindow.kocThroneItems[m];
        itemName = unsafeWindow.kocThroneItems[y.id].name;
        type = "";
        NotUpgrading = true;
        count++;
        
        if (typeof(y.id) == 'number') 
        {
          NotUpgrading = true;

          for (k in ThroneOptions.Items) 
          {
            if (ThroneOptions.Items[k]["id"] == y.id) 
              NotUpgrading = false;
          }
          
          if (count <= (parseInt(Seed.throne.rowNum) * 5) && count > Options.throneSaveNum) 
          {
            // New code to test items for matching lines
            for(itemType in t.ItemTypeList) 
            {
              var item = t.ItemTypeList[itemType];
              
              if (typeof(item) == "string") 
              {
                var itemMatch = item;
                
                if(item == "Windows") 
                {
                  itemMatch = "Window";
                }
                
                if(y.type == itemMatch.toLowerCase()) 
                {
                  boostDelete = true;

                  for(boostType in t.BoostType) 
                  {
                    var boost = t.BoostType[boostType];

                    if(typeof(boost) == "string") 
                    {
                      var saveThreshold = parseInt(ThroneOptions.itemAttributes[item][boost].saveValue);
                      
                      if(saveThreshold == 0) 
                      {
                        continue;
                      }
                      
                      var decrementValue = 1;
                      for (i = 1 ; i <= 5 ; i++){
                        against = CM.thronestats.effects[y.effects["slot"+i].id]["5"][0] || "";
                        wall = CM.thronestats.effects[y.effects["slot"+i].id]["6"][0] || "";
                        boostName = CM.thronestats.effects[y.effects["slot"+i].id]["1"];

                        for (l = 0 ; l < CM.thronestats.effects[y.effects["slot"+i].id]["2"].length ; l++)
                        {
                          type = CM.thronestats.effects[y.effects["slot"+i].id]["2"][l];

                          if (type == boost) 
                          {
                            if (ThroneOptions.ignoreWildBoosts && ( against == "barb" || against == "wild" || against == "df"))
                            {
                            }
                            else 
                            {
                              if (ThroneOptions.ignoreWallBoosts && (wall == "19" || wall == "53" || wall == "60" || wall == "62")) 
                              {
                              }
                              else 
                              {
                                saveThreshold -= decrementValue;
                              }
                            }
                          }
                        }
                        
                        decrementValue *= 2;
                      }
                      
                      if(saveThreshold <= 0) 
                      {
                        boostDelete = false;
                        break;
                      }
                    }
                  }
                }
              }
            }

            if(EnableOptions)
            {
              if (t.applyRules(y.id))
              {
                //logit("Throne: Saving item [enhanced rule] - " + y.name);
                continue;
              }
            }
            
            var protectedItem = (ThroneOptions.protectList.indexOf(y.id) != -1); 
            
            if (boostDelete && NotUpgrading && !y.isEquipped && !y.isBroken && t.LastDeleted != y.id && y.level == 0 && !protectedItem) 
            {
              if(t.SalvageArray.indexOf(y.id) == -1)
              {
                t.SalvageArray.push(y.id);
                jQuery("div#throneInventoryItem" + y.id).addClass('redBorder');
              }
            }          
          }
        }
      }

      if (t.SalvageArray.length == 0) 
      {
        t.SalvageRunning = false;   
      } 
      else 
      {
        logit("Throne: " + t.SalvageArray.length + " items to delete");
        setTimeout(t.doSalvage, 6 * 1000);  
      }
    } 

    // check if we have a nearly full throne room (parseInt(Seed.throne.rowNum)*5)
    if(Options.ThroneSpaceWarning && ((parseInt(itemCount) - t.SalvageArray.length) > ((parseInt(Seed.throne.rowNum) * 5)))) 
    {
      new DisplayAlert('<SPAN class=boldRed>Throne Alert! You throne room is full!!!!</span>', null, null, mainPop.getMainDiv,null);
    } 
    else if(Options.ThroneSpaceWarning && ((parseInt(itemCount) - t.SalvageArray.length) > ((parseInt(Seed.throne.rowNum) * 5) - Options.ThroneSpaceCount))) 
    {
      new DisplayAlert('<SPAN class=boldRed>Throne Alert! You throne room is almost full!</span>', null, null, mainPop.getMainDiv, 10);
    }
  },  

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doSalvage : function()
  {
    var t = Tabs.Throne;  
    var cityid = t.lowestAstoneCity();

    if(t.SalvageArray.length <= 0)
    {
      t.SalvageRunning = false;
      return;
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'salvage';
    params.itemId = t.SalvageArray[0];
    params.cityId = cityid;
    logit("Throne: Salvage request");

    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");

        if(rslt.ok) 
        {
          y =  unsafeWindow.kocThroneItems[params.itemId];
          z = CM.thronestats.effects;
          var msg = y.name;
          var bonus = t.boostPercentage(1, params.itemId) + "% " + z[y.effects["slot1"].id]["1"] + " / "
             + t.boostPercentage(2, params.itemId) + "% " + z[y.effects["slot2"].id]["1"]+ " / "
             + t.boostPercentage(3, params.itemId) + "% " + z[y.effects["slot3"].id]["1"]+ " / "
             + t.boostPercentage(4, params.itemId) + "% " + z[y.effects["slot4"].id]["1"]+ " / "
             + t.boostPercentage(5, params.itemId) + "% " + z[y.effects["slot5"].id]["1"]
          t.addToSalvageLog(msg,rslt.aetherstones,bonus);
          Options.throneDeletedNum++;
          saveOptions();
					delete unsafeWindow.kocThroneItems[params.itemId];
					unsafeWindow.cm.ThroneView.renderInventory(unsafeWindow.kocThroneItems);
          //unsafeWindow.kocThroneItems[params.itemId].salvage();
        } 
        else 
        {
          t.addToSalvageLog("Salvage Failed :(","","");
        }
      },
      
      onFailure: function () 
      {
        return;
      },
    });

    t.SalvageArray.splice(0,1);
    t.LastDeleted = params.itemId;

    if (t.SalvageArray.length > 0) 
    {
      setTimeout(t.doSalvage, 6 * 1000);
    } else {
      t.SalvageRunning = false;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  lowestAstoneCity : function()
  {
    var cityid = 0;
    var lowestCity = 0;
    var lowestStone = 10000000;

    if(ThroneOptions.salvageToMainCity && ThroneOptions.salvageMainCity != 0)
    {
      if(Seed.resources["city" + ThroneOptions.salvageMainCity]["rec5"][0] < 950000)
      {
        cityid = ThroneOptions.salvageMainCity;
      }
    }
    
    for (var k in Cities.byID) 
    {
      if(cityid != 0)
      {
        if(Seed.resources["city" + k]["rec5"][0] < ThroneOptions.salvageToMainLowLimit) 
        {
          lowestStone = parseInt(Seed.resources["city" + k]["rec5"][0]);
          lowestCity = k
          cityid = 0;
        }
      }
      else
      {
        if(Seed.resources["city" + k]["rec5"][0] < lowestStone) 
        {
          lowestStone = parseInt(Seed.resources["city"+k]["rec5"][0]);
          lowestCity = k
        }
      }
    }
    
    if(cityid == 0)
    {
      if (lowestCity == 0) 
      {
        cityid = Seed.cities[0][0];
      } 
      else 
      {
        cityid = lowestCity;
      }
    }
    
    return cityid;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  highestAstoneCity : function()
  {
    var cityid = 0;
    var highestCity = 0;
    var highestStone = 0;

    for (var k in Cities.byID) 
    {
      if(Seed.resources["city"+k]["rec5"][0] > highestStone) 
      {
        highestStone = parseInt(Seed.resources["city"+k]["rec5"][0]);
        highestCity = k
      }
    }
    
    if (highestCity == 0) 
    {
      cityid = Seed.cities[0][0];
    } 
    else 
    {
      cityid = highestCity;
    }

    return cityid;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  boostPercentage : function(slot, item) 
  {
    var throneItem = unsafeWindow.kocThroneItems[item];

    id = throneItem["effects"]["slot" + slot]["id"];
    tier = parseInt(throneItem["effects"]["slot" + slot]["tier"]);
    level = throneItem["level"];
    p = CM.thronestats.tiers[id][tier];
    
    Current = p.base + ((level * level + level) * p.growth * 0.5);
    
    return Current;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide : function ()
  {
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {
    var t = Tabs.Throne;

    if (t.curTabName == 'Sal') 
    {
      t.enhanceStatsTab();
    }
    else if (t.curTabName == 'UPS')
    {
      t.upgradeStatsTab();
    }
    else if (t.curTabName == 'Old')
    {
      t.SalvageTab();
    }
    else if (t.curTabName == 'UE')
    {
      t.Upgrade_Enhance();
    }
    else if (t.curTabName == 'AU')
    {
      t.AutoUpgrade();
    }
    else if (t.curTabName == 'OR')
    {
      t.organizer();
    }
    else if (t.curTabName == 'CO')
    {
      t.Compare();
    }
    else if (t.curTabName == 'ES')
    {
      t.EnhancedSalvage();
    }
    else if (t.curTabName == 'EQ')
    {
      t.Equip();

      for (k in t.ItemTypeList) 
      {
        var y = t.ItemTypeList[k];
        
        if (typeof(y) == "string") 
        {
          what = y.toLowerCase();
          t.paintEquipItemInfo(document.getElementById(what).value, what)
        }
      }
    }
    else if (t.curTabName == 'TC')
    {
      t.Caps();
    }

  },
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support: Throne
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function throneEffectBonus(boost, slot)
{
  var max = "none";
  var min = "none";
  var oldActiveSlot = Seed.throne.activeSlot;
  
  slot = slot || Seed.throne.activeSlot;
  
  boostName = CM.thronestats.effects[boost][2][0];
  
  if(CM.thronestats.boosts[boostName])
  {
    max = CM.thronestats.boosts[boostName].Max;
    min = CM.thronestats.boosts[boostName].Min;
  }
  
  Seed.throne.activeSlot = slot;
  percentage = +CM.ThroneController.effectBonus(boost);
  Seed.throne.activeSlot = oldActiveSlot;
  
  if(max != "none")
  {
    if(percentage > parseInt(max))
    {
      percentage = parseInt(max);
    }
  }

  if(min != "none")
  {
    if(percentage < parseInt(min))
    {
      percentage = parseInt(min);
    }
  }
  
  return percentage;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getRangeStats(stats)
{
  var itemId;
  var rangeStats = 
        {
          range:0, 
          rangeDebuff:0, 
          siegeRange:0, 
          siegeRangeDebuff:0, 
          rangedRange:0, 
          rangedRangeDebuff:0,
          defense:0,
          horsedDefense:0,
        };

  for (itemId in stats) 
  {
    if (stats.hasOwnProperty(itemId)) 
    {
      if (stats[itemId].type.indexOf("Range") != -1) 
      {
        if(stats[itemId].troops[0] == "") 
        {
          if(stats[itemId].percent > 0) 
          {
            rangeStats.range += stats[itemId].percent;
          } 
          else 
          {
            rangeStats.rangeDebuff += Math.abs(stats[itemId].percent)
          }
        }
        
        if(stats[itemId].troops.indexOf("6") != -1) 
        {
          if(stats[itemId].percent > 0) 
          {
            rangeStats.rangedRange += stats[itemId].percent;
          } 
          else 
          {
            rangeStats.rangedRangeDebuff += Math.abs(stats[itemId].percent)
          }
        }
        
        if(stats[itemId].troops.indexOf("12") != -1) 
        {
          if(stats[itemId].percent > 0) 
          {
            rangeStats.siegeRange += stats[itemId].percent;
          } 
          else 
          {
            rangeStats.siegeRangeDebuff += Math.abs(stats[itemId].percent);
          }
        }
      }

      if (stats[itemId].type.indexOf("Defense") != -1) 
      {
        if(stats[itemId].troops[0] == "") 
        {
          if(stats[itemId].percent > 0) 
          {
            rangeStats.defense += stats[itemId].percent;
          } 
        }
        
        if(stats[itemId].troops.indexOf("8") != -1) 
        {
          if(stats[itemId].percent > 0) 
          {
            rangeStats.horsedDefense += stats[itemId].percent;
          } 
        }
      }
    }
  }
  
  logit("Range Stats: " + JSON2.stringify(rangeStats, null, 2));
  
  return rangeStats;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getThroneStats(items)
{
  var stats = {};
  
  for(itemNo in items)
  {
    if(items.hasOwnProperty(itemNo)) 
    {
      var item = items[itemNo];

      var quality = parseInt(item.quality,10);

      for (i = 1 ; i <= 5 ; i++) 
      {
        if (i <= quality) 
        {
          id = item.effects["slot"+i].id;
          tier = parseInt(item.effects["slot"+i].tier,10);
          
          level = item.level;
          
          p = CM.thronestats.tiers[id][tier];

          statName = CM.thronestats.effects[id][1].toString();    
          type = CM.thronestats.effects[id][2];
          troops = CM.thronestats.effects[id][6];            
          
          Current = + (p.base) + ((level * level + level) * +(p.growth) * 0.5);
          // Current = Math.ceil(Current);
        
          if (!stats[id]) 
          {
            stats[id] = {};
            stats[id].percent = 0;
          }
        
          stats[id].percent += Current;
          stats[id].type = type;
          stats[id].name = statName;
          stats[id].troops = troops;
        }
      }
    }
  }
  
  return stats;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function updatePlayerRange(playerId, rangeStats, updated)
{
  var playerStats = Options.attackersRange[playerId];
  var liveStats = SessionOptions.attackersRange[playerId];
  var updateRequired = false;
  var now = unixTime();
  
  var stats = ["siegeRange", "siegeRangeDebuff", "rangedRange", "rangedRangeDebuff", "range", "rangeDebuff"];  
  
  liveStats.siegeRange = rangeStats.siegeRange;
  liveStats.siegeRangeDebuff = rangeStats.siegeRangeDebuff;
  liveStats.rangedRange = rangeStats.rangedRange;
  liveStats.rangedRangeDebuff = rangeStats.rangedRangeDebuff;
  liveStats.range = rangeStats.range;
  liveStats.rangeDebuff = rangeStats.rangeDebuff;
  liveStats.updated = now;

  prevSiegeRange = parseIntWithDefault(playerStats.siegeRange,0) + parseIntWithDefault(playerStats.siegeRangeDebuff,0);
  newSiegeRange = rangeStats.siegeRange + rangeStats.siegeRangeDebuff;
  prevRangedRange = parseIntWithDefault(playerStats.rangedRange,0) + parseIntWithDefault(playerStats.rangedRangeDebuff,0);
  newRangedRange = rangeStats.rangedRange + rangeStats.rangedRangeDebuff;
  prevRange = parseIntWithDefault(playerStats.range,0) + parseIntWithDefault(playerStats.rangeDebuff,0);
  newRange = rangeStats.range + rangeStats.rangeDebuff;
  
  if(playerStats) 
  {
    if(prevRangedRange < newRangedRange) 
    {
      playerStats.rangedRange = rangeStats.rangedRange;
      playerStats.rangedRangeDebuff = rangeStats.rangedRangeDebuff;
      playerStats.lastChanged = now;
      updateRequired = true;
    }

    if(prevRange < newRange) 
    {
      playerStats.range = rangeStats.range;
      playerStats.rangeDebuff = rangeStats.rangeDebuff;
      playerStats.lastChanged = now;
      updateRequired = true;
    }

    if(prevSiegeRange < newSiegeRange) 
    {
      playerStats.siegeRange = rangeStats.siegeRange;
      playerStats.siegeRangeDebuff = rangeStats.siegeRangeDebuff;
      playerStats.lastChanged = now;
      updateRequired = true;
    }

    playerStats.lastChecked = now;

    if(parseIntWithDefault(playerStats.fletch,0) == 0) 
    {
      playerStats.fletch = 12;
      updateRequired = true;
    }
    
    saveOptions();
    
    if(updateRequired)
    {
      logit("Support: the stored range for [" + playerId + "] has increased.");
      if(updated != null)
      {
        logit("Support: call function for updated range");
        updated();
      }
    }
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getMyThroneStats(activeSlot) 
{
  if(activeSlot == undefined)
  {
      activeSlot = Seed.throne.activeSlot;
  }
  
  var activeSlotItems = Seed.throne.slotEquip[activeSlot];
  var items = {};
  var stats;
 
  var slotNumber;
  
  // get the set of items that are active in the current preset
  for(slotNumber in activeSlotItems)
  {
    if(activeSlotItems.hasOwnProperty(slotNumber)) 
    {
      var item = unsafeWindow.kocThroneItems[activeSlotItems[slotNumber]];
      
      items[activeSlotItems[slotNumber]] = item;
    }
  }

  stats = getThroneStats(items); 

  return stats;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function installHandlerFunctions() 
{
  var t = Tabs.Throne;

  // intercept the render menu call for our own uses

  // save the location of the old funtion
  var oldF = unsafeWindow.cm.ContextualMenuThrone.renderMenu;
  var oldMenuButtons = CM.ContextMenuMapController.prototype.calcButtonInfo;
  var oldR = unsafeWindow.cm.ThroneView.renderInventory;
  var oldRenderThrone = unsafeWindow.cm.ThroneView.renderThrone

  var ri2 = function(l) 
  {
    oldR(l);
    jQuery("ul#throneInventoryList > li > div").removeClass('redBorder');
    jQuery("ul#throneInventoryList > li > div").removeClass('yellowBorder');
    jQuery("ul#throneInventoryList > li > div").removeClass('greenBorder');
    jQuery("div#throneMainContainer div#tableContainer").css("left", "290px");
    
    for (i = 0 ; i < t.SalvageArray.length ; i++) 
    {
      jQuery("div#throneInventoryItem" + t.SalvageArray[i]).addClass('redBorder');
    }
    
    for (i = 0 ; i < ThroneOptions.Items.length ; i++)
    {
      jQuery("div#throneInventoryItem" + ThroneOptions.Items[i].id).addClass('yellowBorder');
    }
    
    for (i = 0 ; i < ThroneOptions.protectList.length ; i++)
    {
      jQuery("div#throneInventoryItem" + ThroneOptions.protectList[i]).addClass('greenBorder');
    }
  };

  var renderThrone2 = function(l) 
  {
    oldRenderThrone(l);
    jQuery("div#throneMainContainer div#tableContainer").css("left", "290px");
    jQuery("div#throneMainContainer div#throneInfoContainer ul.tabNavigation").css("height","85px");
  };

  unsafeWindow.cm.ThroneView.renderInventory = ri2;
  unsafeWindow.cm.ThroneView.renderThrone = renderThrone2;

  var mapButtonMenu = function (f, e)
  {
    d = oldMenuButtons(f, e);
    
    if(parseInt(e.user.id) != parseInt(uW.tvuid) && Options.attackersRange[e.user.id] == undefined && e.user.id != null && e.city.id != 0 && e.city.id != null)
    {
      b = {};
      
      b.text = "Range Monitor";
      b.color = "green";
      b.action = function () 
      {
        Tabs.Range.monitorUser(e);
      }
      
      d.push(b);
    }

    if(parseInt(e.user.id) != parseInt(uW.tvuid) && e.user.id != null && e.city.id != 0 && e.city.id != null)
    {
      b = {};
      
      b.text = "Throne Monitor";
      b.color = "green";
      b.action = function () 
      {
        Tabs.Range.quickMonitorUser(e);
      }
      
      d.push(b);
    }

    if(parseInt(e.user.id) != parseInt(uW.tvuid) && Options.attackersRange[e.user.id] && e.user.id != null && e.city.id != 0 && e.city.id != null)
    {
      b = {};
      
      b.text = "Quick Update";
      b.color = "green";
      b.action = function () 
      {
        Tabs.Range.instantUpdate(e);
      }
      
      d.push(b);
    }

    return d;
  }

  var renderMenu2 = function (l, j) 
  {
    // call the old one
    oldF(l,j);

    if (j != null)
    {
      // create a button to set the item to auto-enhance
      var btn4 = document.createElement('a');
      jQuery(btn4).addClass("buttonv2 h20 green")
        .html("Queue to Wond. +5")
        .css('color', 'cyan')
        .click( function () {
          t.autoAddUpgrades(j.id);
          jQuery("#contextMenu").hide();
        });
      
      if(EnableOptions)
      {
        jQuery("#contextMenu div.title").after(btn4);
      }
      
      // create a button to set the item to auto-enhance
      var btn2 = document.createElement('a');
      jQuery(btn2).addClass("buttonv2 h20 green")
        .html("Queue Enhance")
        .css('color', 'yellow')
        .click( function () {
          t.addToQueue(j.id, "Enhance");
        });
      jQuery("#contextMenu div.title").after(btn2);

      // create a button to set the item to auto-update
      var btn = document.createElement('a');
      jQuery(btn).addClass("buttonv2 h20 green")
        .html("Queue Upgrade")
        .css('color', 'blue')
        .click( function () {
          t.addToQueue(j.id, "Upgrade");
        });
      jQuery("#contextMenu div.title").after(btn);

      // create a button to set the item to auto-update with tokens
      var btn3 = document.createElement('a');
      jQuery(btn3).addClass("buttonv2 h20 green")
        .html("Auto Upgrade (Tokens)")
        .css('color', 'blue')
        .click( function () {
          t.autoUpgradeTries = 0;
          t.autoUpgradeMessage = "Auto upgrading - " + j.name;
          t.autoUpgradeTokens(j.id);
          jQuery("#contextMenu").hide();
        });
        
      var btn4 = document.createElement('a');
      jQuery(btn4).addClass("buttonv2 h20 green")
        .html("Protect Item")
        .css('color', 'red')
        .click( function () {
          if(ThroneOptions.protectList.indexOf(j.id) < 0)
          {
            ThroneOptions.protectList.push(j.id);
            logit("Throne: Protect List - " + JSON2.stringify(ThroneOptions.protectList, null, 2));
            jQuery("div#throneInventoryItem" + j.id).addClass('greenBorder');
            saveThroneOptions();
            jQuery("#contextMenu").hide();
          }
        });

      var btn5 = document.createElement('a');
      jQuery(btn5).addClass("buttonv2 h20 green")
        .html("Unprotect Item")
        .css('color', 'red')
        .click( function () {
          var indexValue = ThroneOptions.protectList.indexOf(j.id);
          
          logit("Throne: Protectlist - " + j.id + ", " + indexValue);
          
          if(indexValue >= 0)
          {
            ThroneOptions.protectList.splice(indexValue, 1);
            logit("Throne: Protect List - " + JSON2.stringify(ThroneOptions.protectList, null, 2));
            jQuery("div#throneInventoryItem" + j.id).removeClass('greenBorder');
            saveThroneOptions();
            jQuery("#contextMenu").hide();
          }
        });

      if(Seed.items["i20005"] > Options.autoTrUpgradeLeaveTokens && !j.isBroken && EnableOptions)
      {
        jQuery("#contextMenu div.title").after(btn3);
      }
    }
    jQuery("#contextMenu > a:contains('Mass Salvage')").hide();
    
    
    if(j.level == 0 && EnableOptions)
    {
      if(ThroneOptions.protectList.indexOf(j.id) == -1)
      {
        jQuery("#contextMenu div.title").after(btn4);
      }
      else
      {
        jQuery("#contextMenu div.title").after(btn5);
      }
    }
    
    if(j.level > 0 && ThroneOptions.protectList.indexOf(j.id) != -1 && EnableOptions)
    {
      jQuery("#contextMenu div.title").after(btn5);
    }

    if((j.level > 0 && SessionOptions.protectItems) || ThroneOptions.protectList.indexOf(j.id) != -1 || Tabs.Throne.isQueued(j.id)) 
    {
      jQuery("#contextMenu > a:contains('Salvage')").hide();
    }
    
    if(ThroneOptions.enableMassSalvage)
    {
      jQuery("#contextMenu > a:contains('Mass Salvage')").show();
    }
  };

  // hook up our new function
  CM.ContextualMenuThrone.renderMenu = renderMenu2;
  if(Options.FullEnable)
  {
    CM.ContextMenuMapController.prototype.calcButtonInfo = mapButtonMenu;
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//class definition for rules and conditions
function Rule(type, faction, conditions)
{
  this.type = type;
  this.faction = faction;
  
  if (conditions)
  {
    this.conditions = conditions;
  }
  else
  {
    this.conditions = [];
  }

  this.addCondition = addCondition;
  this.applyRule    = applyRule;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function cloneRule( rule)
{
  this.type = rule.type;
  this.faction = rule.faction;
  this.conditions = [];
  
  if (rule.conditions) 
  {
    this.conditions = rule.conditions;
  }

  this.addCondition = addCondition;
  this.applyRule    = applyRule;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function addCondition(c)
{
  this.conditions.push(c);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function applyRule(id)
{
  var throne_item = unsafeWindow.kocThroneItems[id];

  if (this.type != "any" && (this.type != throne_item.type)) 
  {
    return false;
  }
  
  if (this.faction != "any" && (this.faction != throne_item.faction)) 
  {
    return false;
  }

  for (r in this.conditions)
  {
      if (!this.conditions[r].checkCondition(id)) return false;
  }
  
  return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function Condition(mustHave, number, effect, buffType, slots )
{
  this.mustHave = mustHave;
  this.number   = number;
  this.effect   = effect;
  this.buffType = buffType;
  this.slots    = slots;

  this.checkCondition = checkCondition;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function checkCondition(id)
{
  var numberFound  = 0;
  var effectsFound = false;
  
  // get card
  var throne_item = unsafeWindow.kocThroneItems[id];

  if (!throne_item) 
  {
    return false;
  }

  // for loop for stat
  // count up occurances
  for (i in throne_item.effects)
  {
    var card_effect = CM.thronestats.effects[throne_item.effects[i].id][1];
    var slotid = i.split("slot")[1];

    if (!this.slots[slotid-1])
    {
      continue;
    }

    if ( (this.buffType == "e" || this.buffType == "b") && card_effect == this.effect)
    {
      numberFound++;
    }

    if ( (this.buffType == "e" || this.buffType == "d") && card_effect == (this.effect + " Debuff"))
    {
      numberFound++;
    }
  }

  if ( numberFound >= this.number)
  {
    effectsFound = true;
  }

  if (this.mustHave != "false")
  {
    return effectsFound;
  }
  else
  {
    return (!effectsFound);
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function setPresetWidget(slot)
{
  // logit("preset: " + slot);
  var x = (jQuery("#t_throneStatList .selected, #throneStatList .selected"));
  x.removeClass('selected');
  x.addClass('active');
  
  x.bind("mouseenter", function (I) 
  {
    CM.ThroneView.boostsTooltip(this, I, I.target.id)
  });
  
  x.bind("mouseleave", function (I) 
  {
    unsafeWindow.removeTooltip()
  });

  var s = jQuery("[id^=t_throneInventoryPreset" + slot + "], #t_throneInventoryPreset" + slot + ", #throneInventoryPreset" + slot); 
    
  s.removeClass('active');
  s.addClass('selected')
  s.unbind("mouseenter").unbind("mouseleave");
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function processPresetClick(btn)
{
  // don't do anything if already the right preset
  if (btn == Seed.throne.activeSlot) 
  {
    return;
  }

  // send message
  unsafeWindow.AjaxCall.gPostRequest(
    "ajax/_dispatch53.php",
    {
      ctrl: "throneRoom\\ThroneRoomServiceAjax",
      action: "setPreset",
      presetId: btn
    },
    function (v) 
    {
      if (v.ok === true)
      {
        // success
        var H = Seed.throne.slotEquip[btn];
        Seed.throne.activeSlot = btn;

        // set the right items as equiped
        jQuery.each(unsafeWindow.kocThroneItems, function (I, J) 
        {
          C = jQuery.inArray(J.id, H) > -1;
          
          if (C) 
          {
            J.isEquipped = true
          } 
          else 
          {
            J.isEquipped = false
          }
        });

        // update the buttons
        setPresetWidget(btn);
        CM.ThroneView.renderThrone();
        CM.ThroneView.renderStats();
      }
      else
      {
        logit("Throne: Preset change failed. Error code: " + v.error_code);
      }
    }
  );
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function buildPresetWidget(name)
{
  var E = [];
  var J = Seed.throne.activeSlot;
  var F = Seed.throne.slotNum;

  for (var G = 0; G < 8; ++G) 
  {
    var H = G + 1;
    var I = jQuery("<li/>");

    if (H === J) 
    {
      I.attr("id", "t_throneInventoryPreset" + H + "_" + name);
      I.addClass("selected");
      I.html(H);
      
      I.bind("click", { idx: G }, function (K) 
      {
        var L = K.data.idx + 1;
        processPresetClick(L);
      });
    } 
    else 
    {
      if (H === (F + 1)) 
      {
        I.attr("id", "t_throneInventoryPreset" + H + "_" + name);
        I.addClass("buy");
        I.html(H);
        
        I.bind("click", function () 
        {
          CM.ContextualMenuThrone.renderMenu(this, null);
        });
      } 
      else 
      {
        if (H <= F) 
        {
          I.attr("id", "t_throneInventoryPreset" + H + "_" + name);
          I.addClass("active");
          I.html(H);
          
          I.bind("click", { idx: G }, function (K) 
          {
            var L = K.data.idx + 1;
            processPresetClick(L);
          });
          
          I.bind("mouseenter", function (K) 
          {
            CM.ThroneView.boostsTooltip(this, K, K.target.id)
          });
          
          I.bind("mouseleave", function (K) 
          {
            unsafeWindow.removeTooltip()
          });
        } 
        else 
        {
          I.attr("id", "t_throneInventoryPreset" + H + "_" + name);
          I.addClass("locked");
          I.html(H);
        }
      }
    }
    E.push(I);
  }
  
  var C = jQuery("<ul/>", {
    id: "t_throneStatList",
    addClass: "presetList",
    style: "padding: 0; margin: 5px; list-style: none; overflow: hidden; float: left; border: 5px outset tan;",
  });
  
  jQuery.each(E, function (K, L) 
  {
    C.append(L);
  })

  //$("div.tabs_engagement").append(C);
  //$("div#kocmain_bottom").append(C);
  var aa = jQuery("<div/>", {height: '40px'});
  jQuery(aa).append(C);
  
  return aa;
}

function populatePresetWidget(aa)
{
  jQuery("div.mod_comm").prepend(aa);
  
  var p = jQuery("div.mod_comm").css('top');
  if (+p.split('px')[0] < -611)
  {  
    jQuery("div.mod_comm").css('top', "-610px");
    jQuery("div.comm_body").css('top', '40px');
  }
  
  jQuery("div.mod_comm").bind('DOMAttrModified', function ()
  {
    var p = jQuery("div.mod_comm").css('top');
    if (+p.split('px')[0] < -611)
    {  
      jQuery("div.mod_comm").css('top', "-610px");
      jQuery("div.comm_body").css('top', '40px');
    }
  });
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Tower
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.tower = 
{
  tabOrder: 1,
  tabLabel: 'Tower',
  myDiv: null,
  generateIncomingFunc : null,
  fixTargetEnabled : false,
  secondTimer : null,
  soundPlaying : false,
  defMode : {},  
  soundRepeatTimer : null,
  soundStopTimer : null,
  towerMarches: [],
  throneChangePosted: false,
  closeAttack : false,
  origUCL : null,
  Providers : {
    0: { 'country': "--Country--", 'provider': "--Provider--" },
    1: { 'country': "AUSTRALIA", 'provider': "T-Mobile" },
    2: { 'country': "AUSTRALIA", 'provider': "Optus Zoo" },
    3: { 'country': "AUSTRIA", 'provider': "T-Mobile" },
    4: { 'country': "BULGARIA", 'provider': "Mtel" },
    5: { 'country': "BULGARIA", 'provider': "Globul" },
    6: { 'country': "CANADA", 'provider': "Aliant" },
    7: { 'country': "CANADA", 'provider': "Bell Mobility" },
    8: { 'country': "CANADA", 'provider': "Fido" },
    9: { 'country': "CANADA", 'provider': "MTS Mobility" },
    10: { 'country': "CANADA", 'provider': "Rogers Wireless" },
    11: { 'country': "CANADA", 'provider': "Sasktel Mobility" },
    12: { 'country': "CANADA", 'provider': "Telus" },
    13: { 'country': "CANADA", 'provider': "Virgin Mobile" },
    14: { 'country': "CANADA", 'provider': "Presidents Choice" },
    15: { 'country': "GERMANY", 'provider': "T-Mobile" },
    16: { 'country': "GERMANY", 'provider': "Vodafone" },
    17: { 'country': "GERMANY", 'provider': "O2" },
    18: { 'country': "GERMANY", 'provider': "E-Plus" },
    19: { 'country': "ICELAND", 'provider': "OgVodafone" },
    20: { 'country': "ICELAND", 'provider': "Siminn" },
    21: { 'country': "INDIA", 'provider': "Andhra Pradesh AirTel" },
    22: { 'country': "INDIA", 'provider': "Andhra Pradesh Idea Cellular" },
    23: { 'country': "INDIA", 'provider': "Chennal Skycell Airtel" },
    24: { 'country': "INDIA", 'provider': "Chennel RPG Cellular" },
    25: { 'country': "INDIA", 'provider': "Delhi Airtel" },
    26: { 'country': "INDIA", 'provider': "Delhi Hutch" },
    27: { 'country': "INDIA", 'provider': "Gujarat Idea Cellular" },
    28: { 'country': "INDIA", 'provider': "Gujaret Airtel" },
    29: { 'country': "INDIA", 'provider': "Gujaret Celforce" },
    30: { 'country': "INDIA", 'provider': "Goa Airtel" },
    31: { 'country': "INDIA", 'provider': "Goa BPL Mobile" },
    32: { 'country': "INDIA", 'provider': "Goa Idea Cellular" },
    33: { 'country': "INDIA", 'provider': "Haryana Airtel" },
    34: { 'country': "INDIA", 'provider': "Haryana Escotel" },
    35: { 'country': "INDIA", 'provider': "Himachal Pradesh Airtel" },
    36: { 'country': "INDIA", 'provider': "Karnataka Airtel" },
    37: { 'country': "INDIA", 'provider': "Kerala Airtel" },
    38: { 'country': "INDIA", 'provider': "Kerala Escotel" },
    39: { 'country': "INDIA", 'provider': "Kerala BPL Mobile" },
    40: { 'country': "INDIA", 'provider': "Kolkata Airtel" },
    41: { 'country': "INDIA", 'provider': "Madhya Pradesh Airtel" },
    42: { 'country': "INDIA", 'provider': "Maharashtra Airtel" },
    43: { 'country': "INDIA", 'provider': "Maharashtra BPL Mobile" },
    44: { 'country': "INDIA", 'provider': "Maharashtra Idea Cellular" },
    45: { 'country': "INDIA", 'provider': "Mumbai Airtel" },
    46: { 'country': "INDIA", 'provider': "Mumbai BPL Mobile" },
    47: { 'country': "INDIA", 'provider': "Punjab Airtel" },
    48: { 'country': "INDIA", 'provider': "Pondicherry BPL Mobile" },
    49: { 'country': "INDIA", 'provider': "Tamil Nadu Airtel" },
    50: { 'country': "INDIA", 'provider': "Tamil Nadu BPL Mobile" },
    51: { 'country': "INDIA", 'provider': "Tamil Nadu Aircel" },
    52: { 'country': "INDIA", 'provider': "Uttar Pradesh West Escotel" },
    53: { 'country': "IRELAND", 'provider': "Meteor" },
    54: { 'country': "IRELAND", 'provider': "Meteor MMS" },
    55: { 'country': "ITALY", 'provider': "TIM" },
    56: { 'country': "ITALY", 'provider': "Vodafone" },
    57: { 'country': "JAPAN", 'provider': "AU by KDDI" },
    58: { 'country': "JAPAN", 'provider': "NTT DoCoMo" },
    59: { 'country': "JAPAN", 'provider': "Vodafone Chuugoku/Western" },
    60: { 'country': "JAPAN", 'provider': "Vodafone Hokkaido" },
    61: { 'country': "JAPAN", 'provider': "Vodafone Hokuriko/Central North" },
    62: { 'country': "JAPAN", 'provider': "Vodafone Kansai/West, including Osaka" },
    63: { 'country': "JAPAN", 'provider': "Vodafone Kanto/Koushin/East including Tokyo" },
    64: { 'country': "JAPAN", 'provider': "Vodafone Kyuushu/Okinawa" },
    65: { 'country': "JAPAN", 'provider': "Vodafone Shikoku" },
    66: { 'country': "JAPAN", 'provider': "Vodafone Touhoku/Niigata/North" },
    67: { 'country': "JAPAN", 'provider': "Vodafone Toukai/Central" },
    68: { 'country': "JAPAN", 'provider': "Willcom" },
    69: { 'country': "JAPAN", 'provider': "Willcom di" },
    70: { 'country': "JAPAN", 'provider': "Willcom dj" },
    71: { 'country': "JAPAN", 'provider': "Willcom dk" },
    72: { 'country': "NETHERLANDS", 'provider': "T-Mobile" },
    73: { 'country': "NETHERLANDS", 'provider': "Orange" },
    74: { 'country': "SINGAPORE", 'provider': "M1" },
    75: { 'country': "SOUTH AFRICA", 'provider': "Vodacom" },
    76: { 'country': "SPAIN", 'provider': "Telefonica Movistar" },
    77: { 'country': "SPAIN", 'provider': "Vodafone" },
    78: { 'country': "SWEDEN", 'provider': "Tele2" },
    79: { 'country': "UNITED STATES", 'provider': "Teleflip" },
    80: { 'country': "UNITED STATES", 'provider': "Alltel" },
    81: { 'country': "UNITED STATES", 'provider': "Ameritech" },
    82: { 'country': "UNITED STATES", 'provider': "ATT Wireless" },
    83: { 'country': "UNITED STATES", 'provider': "Bellsouth" },
    84: { 'country': "UNITED STATES", 'provider': "Boost" },
    85: { 'country': "UNITED STATES", 'provider': "CellularOne" },
    86: { 'country': "UNITED STATES", 'provider': "CellularOne MMS" },
    87: { 'country': "UNITED STATES", 'provider': "Cingular" },
    88: { 'country': "UNITED STATES", 'provider': "Edge Wireless" },
    89: { 'country': "UNITED STATES", 'provider': "Sprint PCS" },
    90: { 'country': "UNITED STATES", 'provider': "T-Mobile" },
    91: { 'country': "UNITED STATES", 'provider': "Metro PCS" },
    92: { 'country': "UNITED STATES", 'provider': "Nextel" },
    93: { 'country': "UNITED STATES", 'provider': "O2" },
    94: { 'country': "UNITED STATES", 'provider': "Orange" },
    95: { 'country': "UNITED STATES", 'provider': "Qwest" },
    96: { 'country': "UNITED STATES", 'provider': "Rogers Wireless" },
    97: { 'country': "UNITED STATES", 'provider': "Telus Mobility" },
    98: { 'country': "UNITED STATES", 'provider': "US Cellular" },
    99: { 'country': "UNITED STATES", 'provider': "Verizon" },
    100: { 'country': "UNITED STATES", 'provider': "Virgin Mobile" },
    101: { 'country': "UNITED KINGDOM", 'provider': "O2 1" },
    102: { 'country': "UNITED KINGDOM", 'provider': "O2 2" },
    103: { 'country': "UNITED KINGDOM", 'provider': "Orange" },
    104: { 'country': "UNITED KINGDOM", 'provider': "T-Mobile" },
    105: { 'country': "UNITED KINGDOM", 'provider': "Virgin Mobile" },
    106: { 'country': "UNITED KINGDOM", 'provider': "Vodafone" },
    107: { 'country': "BELGIUM", 'provider': "mobistar" },
    108: { 'country': "GERMANY", 'provider': "1und1" },
    109: { 'country': "UNITED STATES", 'provider': "MyCricket" },
    110: { 'country': "Philippines", 'provider': "Smart" },
    111: { 'country': "UNITED STATES", 'provider': "CellularSouth" },
    112: { 'country': "UNITED STATES", 'provider': "Viaero" },
    113: { 'country': "CANADA", 'provider': "Wind Mobile" }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init: function(div)
  {
    var t = Tabs.tower;
    t.myDiv = div;

    if (GM_getValue ('towerMarches_'+getServerId()) != null) 
    {
      GM_deleteValue ('towerMarches_'+getServerId());   // remove deprecated data if it exists
    // t.generateIncomingFunc = new CalterUwFunc ('attack_generateincoming', [[/.*} else {\s*e = true;\s*}/im, '} else { e = ptGenerateIncoming_hook(); }']]);
    // unsafeWindow.ptGenerateIncoming_hook = t.generateIncoming_hook;
    }
    
    var m = '<DIV class=pbStat>TOWER ALERTS</div>';
    m += '<TABLE class=pbTab><TR align=center>';

    for (var i=0; i<Cities.cities.length; i++) 
    {
      m += '<TD width=95><SPAN id=pbtacity_'+ i +'>' + Cities.cities[i].name + '</span></td>';
    }
    
    m += '</tr><TR align=center>';
    
    for (var cityId in Cities.byID) 
    {
      m += '<TD><INPUT type=submit id=pbtabut_'+ cityId +' value=""></td>';
    }
    
    m += '</tr><TR align=center>';
    
    for (var cityId in Cities.byID)
    {
      m += '<TD><CENTER><INPUT id=pbattackqueue_' + cityId + ' type=submit value="A 0 | S 0"></center></td>';
    }
    
    m += '</tr></table>';
    m += '<BR><DIV><CENTER><INPUT id=pbSoundStop type=submit value="'+translate("Stop Sound Alert")+'"></center></div><DIV id=pbSwfPlayer></div>';
    m += '<BR><DIV class=pbStat>'+translate("CONFIGURATION")+'</div>';
    m += '<TABLE class=pbTab>\
      <tr><td align=left><INPUT id=pbcellenable type=checkbox '+ (Options.celltext.atext?'CHECKED ':'') +'/></td>\
      <td align=left>'+translate("Text message incoming attack to")+': <INPUT id=pbnum1 type=text size=4 maxlength=4 value="'+ Options.celltext.num1 +'"  '+(Options.celltext.provider==0?'DISABLED':'')+'\>\
      &nbsp;<INPUT id=pbnum2 type=text size=3 maxlength=3 value="'+ Options.celltext.num2 +'"  '+(Options.celltext.provider==0?'DISABLED':'')+'\>\
      &nbsp;<INPUT id=pbnum3 type=text size=4 maxlength=4 value="'+ Options.celltext.num3 +'"  '+(Options.celltext.provider==0?'DISABLED':'')+'\> <span style="color:#800; font-weight:bold"><sup>*'+translate("Standard text messaging rates apply")+'</sup></span></td></tr><tr><td></td>\
      <TD align=left>'+translate("Country")+': <select id="pbfrmcountry">';

    for (var i in t.Providers) 
    {
      var ret=m.indexOf(t.Providers[i].country);

      if (ret==-1) 
      {
         if (t.Providers[i].country==t.Providers[Options.celltext.provider].country) 
         {
           m += '<option value="'+t.Providers[i].country+'" selected="selected">'+t.Providers[i].country+'</option>'; // Load Previous Provider Selection
         }
         else 
         {
           m += '<option value="'+t.Providers[i].country+'">'+t.Providers[i].country+'</option>';
         }
      }
    }

    m += '</select>';
    m += '<select id="pbfrmprovider" '+(Options.celltext.provider==0?'DISABLED':'')+'><option value=0 >--'+translate("Provider")+'--</option>';
    
    for (var i in t.Providers) 
    {
      if(t.Providers[i].country == t.Providers[Options.celltext.provider].country)
      {
        if(Options.celltext.provider == i)
        {
          m += '<option value="'+i+'" selected="selected">'+t.Providers[i].provider+'</option>'; // Load Previous Provider Selection
        }
        else
        {
          m += '<option value="'+i+'">'+t.Providers[i].provider+'</option>';
        }
      }
    }
    
    m += '</select></td></tr>';
    m += '<TR><TD><INPUT id=pbEnableTowerMonitoring type=checkbox '+ (SessionOptions.towerMonitorEnable?'CHECKED ':'') +'/></td><TD>' + translate("Enable Tower Monitoring")+'<span style="color:#800; font-weight:bold">&nbsp;(This disables and overrides all tower features!!)</span> </td></tr>';
    m += '<TR><TD><INPUT id=pbalertEnable type=checkbox '+ (Options.alertConfig.aChat?'CHECKED ':'') +'/></td><TD>'+translate("Automatically post incoming attacks to alliance chat")+'.</td></tr>';
    m += '<TR><TD></td><TD>';
    m += '<TABLE class=pbOptions cellpadding=0 cellspacing=0></td></tr>';
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Tower options
    m += '<TR><TD align=right>' + translate("Message Prefix")+': &nbsp; </td><TD><INPUT id=pbalertPrefix type=text size=60 maxlength=120 value="'+ Options.alertConfig.aPrefix +'" \></td></tr>';
    m += '<TR><TD align=right>' + translate("Alert on scouting")+': &nbsp; </td><TD><INPUT id=pbalertScout type=checkbox '+ (Options.alertConfig.scouting?'CHECKED ':'') +'/></td></tr>';
    m += '<TR><TD align=right>' + translate("Alert on wild attack")+': &nbsp; </td><TD><INPUT id=pbalertWild type=checkbox '+ (Options.alertConfig.wilds?'CHECKED ':'') +'/></td></tr>';
    m += '<TR><TD align=right>' + translate("Display defend status")+': &nbsp; </td><TD><INPUT id=pbalertDefend type=checkbox '+ (Options.alertConfig.defend?'CHECKED ':'') +'/></td></tr>';
    m += '<TR><TD align=right>' + translate("Minimum # of troops")+': &nbsp; </td><TD><INPUT id=pbalertTroops type=text size=7 value="'+ Options.alertConfig.minTroops +'" \> &nbsp; &nbsp; <span id=pbalerterr></span></td></tr>';
    m += '<TR><TD align=right>' + translate("Post desertion messages to alliance chat") + '</td><TD><INPUT id=desertionChatEnabled type=checkbox '+ (Options.desertionChatEnabled?'CHECKED ':'') +'/></td></tr>';
    m += '<TR><TD align=right>' + translate("Stop raids on impending")+'.</td><TD><INPUT id=pbalertraid type=checkbox '+ (Options.alertConfig.raid?'CHECKED':'') +'/></td></tr>';

    m += '</table>';
    m += '</table>';
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Throne options
    m += '<DIV id=pbThroneHeading class=pbStat>Throne Options [Change Throne on Attack : <span id=pbThroneState>' + (Options.throneAttackSlotEnable ? 'ON' : 'OFF') + '</span>]<span id=pbThroneIcon class=down></span></div>';
    m += '<div id=pbThroneOptions>';
    m += '<table class=pbOptions cellpadding=0 cellspacing=0>';
    m += '<TR><TD align=right>'+translate("Change throne preset on attack")+': &nbsp; </td><TD><INPUT id=throneAttackSlotEnable type=checkbox '+ (Options.throneAttackSlotEnable?'CHECKED ':'') +'/></td></tr>';
    m += '<TR><TD align=right>'+translate("Throne preset to set when attacked")+': &nbsp; </td><TD><SELECT id=pbThronePreset type=list></select></td></tr>';
    m += '<TR><TD align=right>'+translate("Throne preset when no attacks incoming")+': &nbsp; </td><TD><SELECT id=pbThronePresetNoAttacks type=list></select></td></tr>';
    m += '<TR><TD align=right>'+translate("Period without attacks before switching")+': &nbsp; </td><TD><INPUT id = pbalertTRsetmin type=text size=3 maxlength=3 value="'+ Options.thronePresetTrainingWaitTime +'"> minutes.</td></tr>';
    if(EnableOptions)
    {
      m += '<TR><TD align=right>'+translate("Range configuration warning")+': &nbsp; </td><TD><INPUT id=towerRangeWarning type=checkbox '+ (Options.towerRangeWarning?'CHECKED ':'') +'/></td></tr>';
    }
    
    if(Options.FullEnable) 
    {
      m += '<TR><TD align=right>'+translate("Throne preset when archers attacking")+': &nbsp; </td><td><SELECT id=pbThronePresetArchers type=list></select></td></tr>';
      //m += '<TR><TD align=right>'+translate("Throne attacking preset")+': &nbsp; </td><td><SELECT id=pbThronePresetAttacking type=list></select></td></tr>';
      m += '<TR><TD align=right>'+translate("Throne preset when hiding")+': &nbsp; </td><td><SELECT id=pbThronePresetHiding type=list></select></td></tr>';
      m += '<TR><TD align=right>'+translate("Throne preset when being scouted")+': &nbsp; </td><td><SELECT id=pbThronePresetScout type=list></select></td></tr>';
      m += '<TR><TD align=right>'+translate("Throne preset when non range attacking")+': &nbsp; </td><td><SELECT id=pbThronePresetNonRange type=list></select></td></tr>';
      m += '<TR><TD align=right>'+translate("Max range troops to consider non range")+': &nbsp; </td><td><INPUT id=pbThroneNonRangeLimit type=text size=7 value="'+ Options.throneNonRangeLimit +'" \> &nbsp; </td></tr>';
      //m += '<TR><TD align=right>' + translate("Use Live Throne Range [!! Experimental !!]")+'.</td><TD><INPUT id=pbLiveRange type=checkbox '+ (Options.liveRange?'CHECKED':'') +'/></td></tr>';
    }
    m += '</table>';
    m += '</div>';
    m += '<br>';

    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Guardian options
    m += '<DIV id=pbGuardianHeading class=pbStat>Guardian Options [Guardian Change State : <span id=pbGuardianState>' + (Options.changeGuardianOnAttack ? 'ON' : 'OFF') + '</span>]<span id=pbGuardianIcon class=down></span></div>';
    m += '<div id=pbGuardianOptions>';
    m += '<table class=pbOptions cellpadding=0 cellspacing=0>';
    m+=  '<TR><TD align=right>'+translate("Change guardian type to wood on attack")+': &nbsp; </td><TD><INPUT id=changeGuardianOnAttack type=checkbox '+ (Options.changeGuardianOnAttack?'CHECKED ':'') +'/></td></tr>';
    m += '</table>';
    m += '</div>';
    m += '<br>';

    if(Options.FullEnable) 
    {
      /////////////////////////////////////////////////////////////////////////////////////////////////////////
      // Auto-hide options
      m += '<DIV id=pbAutoHideHeading class=pbStat>Auto Hide Options [Auto Hide State : <span id=pbAutoHideState>' + (Options.autoHideEnable ? 'ON' : 'OFF') + '</span>]<span id=pbAutoHideIcon class=down></span></div>';
      m += '<div id=pbAutoHideOptions>';
      m += '<table class=pbOptions cellpadding=0 cellspacing=0>';
      m += '<TR><TD align=right>'+translate("Enable")+': &nbsp; </td><TD><INPUT id=autoHideEnable type=checkbox '+ (Options.autoHideEnable ? 'CHECKED ' : '') +'/></td></tr>';
      m += '<TR><TD align=right>'+translate("Hide from scout killers")+': &nbsp; </td><TD><INPUT id=autoHideScoutKillers type=checkbox '+ (Options.autoHideScoutKillers ? 'CHECKED ' : '') +'/></td></tr>';
      m += '<TR><TD align=right>'+translate("Assume attacker sacrificed")+': &nbsp; </td><TD><INPUT id=assumeAttackSacrifice type=checkbox '+ (Options.assumeAttackSacrifice ? 'CHECKED ' : '') +'/></td></tr>';
      m += '<TR><TD align=right>'+translate("Hide from cav killers")+': &nbsp; </td><TD><INPUT id=autoHideHorseKillers type=checkbox '+ (Options.autoHideHorseKillers ? 'CHECKED ' : '') +'/></td></tr>';
      m += '<TR><TD align=right>'+translate("Kill wagons")+': &nbsp; </td><TD><INPUT id=autoHideKillWagons type=checkbox '+ (Options.autoHideKillWagons?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>'+translate("Switch time")+': &nbsp; </td><TD><INPUT id=autoHideTime type=text size=7 value="'+ Options.autoHideTime +'" \>'+translate("secs")+' &nbsp;</td></tr>';
      m += '<TR><TD align=right>'+translate("Troop count")+': &nbsp; </td><TD><INPUT id=autoHideTroopCount type=text size=7 value="'+ Options.autoHideTroopCount +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>'+translate("Wagon count")+': &nbsp; </td><TD><INPUT id=autoHideWagonThreshold type=text size=7 value="'+ Options.autoHideWagonThreshold +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>'+translate("Boot range reinforcements")+': &nbsp; </td><TD><INPUT id=bootRangeReinforcementHiding type=checkbox '+ (Options.bootRangeReinforcementHiding?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>'+translate("Range reinforement threshold")+': &nbsp; </td><TD><INPUT id=rangeReinforcementThreshold type=text size=7 value="'+ Options.rangeReinforcementThreshold +'" \> &nbsp;</td></tr>';
      m += '</table>';
      m += '</div>';
      m += '<br>';
      /////////////////////////////////////////////////////////////////////////////////////////////////////////
      // Auto-defend options
      m += '<DIV id=pbAutoDefendHeading class=pbStat>Auto Defend Options [Auto Defend State : <span id=pbAutoDefendState>' + (Options.autoDefendEnable?'ON':'OFF') + '</span>]<span id=pbAutoSacrificeIcon class=down></span></div>';
      m += '<div id=pbAutoDefendOptions>';
      m += '<table class=pbOptions cellpadding=0 cellspacing=0>';
      m += '<TR><TD align=right>' + translate("Enable") + ': &nbsp; </td><TD><INPUT id=autoDefendEnable type=checkbox '+ (Options.autoDefendEnable?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>' + translate("Defending troop threshold") + ': &nbsp; </td><TD><INPUT id=hideDefendingThreshold type=text size=7 value="'+ Options.hideDefendingThreshold +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>' + translate("Defending cavalry threshold") + ': &nbsp; </td><TD><INPUT id=autoDefendHorseCount type=text size=7 value="'+ Options.autoDefendHorseCount +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>' + translate("Defend against wagons (limit set in auto-hide)") + ': &nbsp; </td><TD><INPUT id=autoDefendWagons type=checkbox '+ (Options.autoDefendWagons?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>' + translate("Defend against HC") + ': &nbsp; </td><TD><INPUT id=autoDefendHideHC type=checkbox '+ (Options.autoDefendHideHC?'CHECKED ':'') +'/><INPUT id=autoDefendHCHideCount type=text size=7 value="'+ Options.autoDefendHCHideCount +'" \></td></tr>';
      m += '<TR><TD align=right>' + translate("Defend against Siege Wall") + ': &nbsp; </td><TD><INPUT id=autoDefendHideSiegeWall type=checkbox '+ (Options.autoDefendHideSiegeWall?'CHECKED ':'') +'/><INPUT id=autoDefendSWHideCount type=text size=7 value="'+ Options.autoDefendSWHideCount +'" \></td></tr>';
      m += '<TR><TD align=right>' + translate("Protect against might losses") + ': &nbsp; </td><TD><INPUT id=autoDefendMightLossLimitEnable type=checkbox '+ (Options.autoDefendMightLossLimitEnable?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>' + translate("Might loss limit") + ': &nbsp; </td><TD><INPUT id=hideDefendingThreshold type=text size=9 value="'+ Options.autoDefendMightLossLimit +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>' + translate("Reset base might level") + ': &nbsp; </td><TD><a class="button20" id="resetBaseMight"><span>Reset Base Might</span></a>&nbsp;&nbsp;&nbsp;(<span id=baseMightLevel>' + Options.autoDefendMightLossLimitBase + '</span>)</td></tr>';

      m += '<TR><TD align=right>Auto defend from Cities</td><td>';
      var cityCount = 1;
      for (var cityId in Cities.byID)
      {
        var defendState = false;
        if(Options.autoDefendCities[cityId])
        {
          defendState = true;
        }
        
        m += cityCount + ':<INPUT id=autoDefendCities_' + cityId + ' type=checkbox '+ (defendState ? 'CHECKED ' : '') + '/>&nbsp;&nbsp;';
        cityCount += 1;
      }
      m += '</td></tr>';
      
      m += '</table>';
      m += '</div>';
      m += '<br>';
      /////////////////////////////////////////////////////////////////////////////////////////////////////////
      // Auto-sacrifice options
      m += '<DIV id=pbAutoSacrificeHeading class=pbStat>Auto Sacrifice Options [Auto Sacrifice State : <span id=pbAutoSacrificeState>' + (Options.autoSacrificeEnable?'ON':'OFF') + '</span>]<span id=pbAutoDefendIcon class=down></span></div>';
      m += '<div id=pbAutoSacrificeOptions>';
      m += '<table class=pbOptions cellpadding=0 cellspacing=0>';
      m += '<TR><TD align=right>' + translate("Enable") + ': &nbsp; </td><TD><INPUT id=autoSacrificeEnable type=checkbox '+ (Options.autoSacrificeEnable?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>' + translate("Number of troops to sacrifice") + ': &nbsp; </td><TD><INPUT id=autoSacrificeTroopCount type=text size=5 value="'+ Options.autoSacrificeTroopCount +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>' + translate("Max number of sacrifices") + ': &nbsp; </td><TD><INPUT id=autoSacrificeMaxSacrifices type=text size=9 value="'+ Options.autoSacrificeMaxSacrifices +'" \> &nbsp;</td></tr>';
      m += '<TR><TD align=right>' + translate("Troop type to sacrifice") + ': &nbsp; </td><TD><select id=autoSacrificeTroopType>';
      m += '<option value=6>Archers</option>';
      m += '<option value=10>Ballista</option>';
      m += '<option value=12>Catapults</option>';
      m += '</select></td></tr>';
      m += '<TR><TD align=right>' + translate("Number of troops required") + ': &nbsp; </td><TD><INPUT id=autoSacrificeTroopsRequired type=text size=9 value="'+ Options.autoSacrificeTroopsRequired +'" \> &nbsp; (will not sacrifice when less than this present)</td></tr>';
      m += '<TR><TD align=right>' + translate("Sacrifice HC along with cats") + ': &nbsp; </td><TD><INPUT id=autoSacrificeHC type=checkbox '+ (Options.autoSacrificeHC?'CHECKED ':'') +'/></td></tr>';
      m += '<TR><TD align=right>' + translate("Auto reset count time") + ': &nbsp; </td><TD><select id=autoSacrificeResetTime>';
      m += '<option value=9999999>Off</option>';
      m += '<option value=3>3 hrs</option>';
      m += '<option value=6>6 hrs</option>';
      m += '<option value=12>12 hrs</option>';
      m += '<option value=24>24 hrs</option>';
      m += '</select></td></tr>';
      m += '<TR><TD align=right>' + translate("Reset sacrifice count") + ': &nbsp; </td><TD><a class="button20" id="resetSacrificeCount"><span>Reset Count</span></a></td></tr>';
      m += '</table>';
      m += '</div>';
      m += '<br>';
    }
    
    m += '<DIV id=pbSoundHeading class=pbStat>Sound Options<span id=pbSoundState></span><span id=pbSoundIcon class=down></span></div>';
    m += '<div id=pbSoundOptions>';
    m += '<table class=pbOptions cellpadding=0 cellspacing=0>';
    m += '<TR><TD><INPUT id=pbSoundEnable type=checkbox '+ (Options.alertSound.enabled?'CHECKED ':'') +'/></td><TD>'+translate("Play sound on incoming attack/scout")+'</td></tr>\
      <TR><TD></td><TD><DIV id=pbLoadingSwf>'+translate("Loading SWF player")+'</div><DIV style="display:none" id=pbSoundOpts><TABLE cellpadding=0 cellspacing=0>\
      <TR><TD align=right>'+translate("Sound file")+': &nbsp; </td><TD><INPUT id=pbsoundFile type=text size=40 maxlength=1000 value="'+ Options.alertSound.soundUrl +'" \>\
      &nbsp; </td><TD><INPUT id=pbSoundLoad type=submit value='+translate("Load")+' ><INPUT id=pbSoundDefault type=submit value='+translate("Default")+' ></td></tr>\
      <TR><TD align=right>'+translate("Volume")+': &nbsp; </td><TD><TABLE cellpadding=0 cellspacing=0 class=pbTab><TR valign=middle><TD><SPAN id=pbVolSlider></span></td><TD width=15></td><TD align=right id=pbVolOut>0</td></td></table></td><TD align=center><SPAN id=pbLoadStat>xx</span></td></tr>\
      <TR><TD align=right><INPUT id=pbSoundRepeat type=checkbox '+ (Options.alertSound.repeat?'CHECKED ':'') +'/></td><TD> '+translate("Repeat every")+' <INPUT id=pbSoundEvery type=text size=2 maxlength=5 value="'+ Options.alertSound.repeatDelay +'"> '+translate("minutes")+'</td></tr>\
      <TR><TD></td><TD>Play for <INPUT id=pbSoundLength type=text size=3 maxlength=5 value="'+ Options.alertSound.playLength +'"> '+translate("seconds")+'</td></tr>\
      <TR><TD></td><TD><INPUT type=submit value="'+translate("Play Now")+'" id=pbPlayNow></td></tr></table></div></td></tr>';
      m += '</table>';
      m += '</div>';
      m += '<br>';

    t.myDiv.innerHTML = m;

    jQuery("#pbLiveRange").change(function()
    {
      Options.liveRange = this.checked;
      saveOptions();
    });

    jQuery('#pbAutoHideOptions').hide();
    jQuery('#pbAutoDefendOptions').hide();
    jQuery('#pbAutoSacrificeOptions').hide();
    jQuery('#pbGuardianOptions').hide();
    jQuery('#pbThroneOptions').hide();
    jQuery('#pbSoundOptions').hide();
    
    jQuery("#pbThronePresetNoAttacks").append(
      jQuery('<option></option>').val(0).html("---")
    );
    jQuery("#pbThronePresetArchers").append(
      jQuery('<option></option>').val(0).html("---")
    );
    jQuery("#pbThronePresetHiding").append(
      jQuery('<option></option>').val(0).html("---")
    );
    jQuery("#pbThronePresetNonRange").append(
      jQuery('<option></option>').val(0).html("---")
    );
    jQuery("#pbThronePresetScout").append(
      jQuery('<option></option>').val(0).html("---")
    );

    jQuery('#pbAutoHideHeading').click(function()
    {
      jQuery('#pbAutoHideOptions').slideToggle('fast');
      if(jQuery('#pbAutoHideIcon').hasClass('up'))
      {
        jQuery('#pbAutoHideIcon').removeClass('up');
        jQuery('#pbAutoHideIcon').addClass('down');
      }
      else
      {
        jQuery('#pbAutoHideIcon').removeClass('down');
        jQuery('#pbAutoHideIcon').addClass('up');
      }
    });
    
    jQuery('#pbAutoSacrificeHeading').click(function()
    {
      jQuery('#pbAutoSacrificeOptions').slideToggle('fast');
      if(jQuery('#pbAutoSacrificeIcon').hasClass('up'))
      {
        jQuery('#pbAutoSacrificeIcon').removeClass('up');
        jQuery('#pbAutoSacrificeIcon').addClass('down');
      }
      else
      {
        jQuery('#pbAutoSacrificeIcon').removeClass('down');
        jQuery('#pbAutoSacrificeIcon').addClass('up');
      }
    });
    
    jQuery('#pbSoundHeading').click(function()
    {
      jQuery('#pbSoundOptions').slideToggle('fast');
      if(jQuery('#pbSoundIcon').hasClass('up'))
      {
        jQuery('#pbSoundIcon').removeClass('up');
        jQuery('#pbSoundIcon').addClass('down');
      }
      else
      {
        jQuery('#pbSoundIcon').removeClass('down');
        jQuery('#pbSoundIcon').addClass('up');
      }
    });

    jQuery('#pbGuardianHeading').click(function()
    {
      jQuery('#pbGuardianOptions').slideToggle('fast');
      if(jQuery('#pbGuardianIcon').hasClass('up'))
      {
        jQuery('#pbGuardianIcon').removeClass('up');
        jQuery('#pbGuardianIcon').addClass('down');
      }
      else
      {
        jQuery('#pbGuardianIcon').removeClass('down');
        jQuery('#pbGuardianIcon').addClass('up');
      }
    });
    
    jQuery('#pbThroneHeading').click(function()
    {
      jQuery('#pbThroneOptions').slideToggle('fast');
      if(jQuery('#pbThroneIcon').hasClass('up'))
      {
        jQuery('#pbThroneIcon').removeClass('up');
        jQuery('#pbThroneIcon').addClass('down');
      }
      else
      {
        jQuery('#pbThroneIcon').removeClass('down');
        jQuery('#pbThroneIcon').addClass('up');
      }
    });

    jQuery('#pbAutoDefendHeading').click(function()
    {
      jQuery('#pbAutoDefendOptions').slideToggle('fast');
      if(jQuery('#pbAutoDefendIcon').hasClass('up'))
      {
        jQuery('#pbAutoDefendIcon').removeClass('up');
        jQuery('#pbAutoDefendIcon').addClass('down');
      }
      else
      {
        jQuery('#pbAutoDefendIcon').removeClass('down');
        jQuery('#pbAutoDefendIcon').addClass('up');
      }
    });

    for (i=1;i<=Seed.throne.slotNum;i++)
    {
      var o = document.createElement("option");     
      o.text = i;
      o.value = i;
      document.getElementById("pbThronePreset").options.add(o);
      jQuery("#pbThronePresetArchers").append(
        jQuery('<option></option>').val(i).html(i)
      );
      jQuery("#pbThronePresetHiding").append(
        jQuery('<option></option>').val(i).html(i)
      );
      jQuery("#pbThronePresetAttacking").append(
        jQuery('<option></option>').val(i).html(i)
      );
      jQuery("#pbThronePresetNonRange").append(
        jQuery('<option></option>').val(i).html(i)
      );
      jQuery("#pbThronePresetNoAttacks").append(
        jQuery('<option></option>').val(i).html(i)
      );
      jQuery("#pbThronePresetScout").append(
        jQuery('<option></option>').val(i).html(i)
      );
    }
    
    jQuery("#pbThronePresetArchers").val(Options.thronePresetArchers);
    jQuery("#pbThronePresetHiding").val(Options.thronePresetHiding);
    jQuery("#pbThronePresetAttacking").val(Options.thronePresetAttacking);
    jQuery("#pbThronePresetNonRange").val(Options.thronePresetNonRange);
    jQuery("#pbThronePresetNoAttacks").val(Options.thronePresetTraining);
    jQuery("#pbThronePresetScout").val(Options.thronePresetScout);
    jQuery("#autoSacrificeResetTime").val(Options.autoSacrificeResetTime);
    
    jQuery('[id^=autoDefendCities_]').change(function()
    {
      var cityId = this.id.substr(17);
      Options.autoDefendCities[cityId] = this.checked;
      saveOptions();
    });
    
    jQuery('#pbalertTRsetmin').change(function()
    {
      Options.thronePresetTrainingWaitTime = this.value;
      saveOptions();
    });
    jQuery("#pbThronePresetArchers").change(function()
    {
      Options.thronePresetArchers = this.value;
      saveOptions();
    });
    jQuery("#pbThronePresetHiding").change(function()
    {
      Options.thronePresetHiding = this.value;
      saveOptions();
    });
    jQuery("#pbThronePresetAttacking").change(function()
    {
      Options.thronePresetAttacking = this.value;
      saveOptions();
    });
    jQuery("#pbThronePresetNonRange").change(function()
    {
      Options.thronePresetNonRange = this.value;
      saveOptions();
    });
    jQuery("#pbThronePresetNoAttacks").change(function()
    {
      Options.thronePresetTraining = this.value;
      saveOptions();
    });
    jQuery("#pbThronePresetScout").change(function()
    {
      Options.thronePresetScout = this.value;
      saveOptions();
    });
    
    jQuery("#autoDefendHCHideCount").change(function()
    {
      Options.autoDefendHCHideCount = this.value;
      saveOptions();
    });

    jQuery("#autoDefendSWHideCount").change(function()
    {
      Options.autoDefendSWHideCount = this.value;
      saveOptions();
    });

    jQuery("#autoDefendMightLossLimit").change(function()
    {
      Options.autoDefendMightLossLimit = this.value;
      saveOptions();
    });

    jQuery("#autoDefendMightLossLimitEnable").change(function()
    {
      Options.autoDefendMightLossLimitEnable = this.checked;
      saveOptions();
    });

    jQuery('#resetBaseMight').click(function()
    {
      Options.autoDefendMightLossLimitBase = Seed.player.might;
      Options.autoDefendMightLossLimitTrip = false;
      saveOptions();
      jQuery('#baseMightLevel').text(Options.autoDefendMightLossLimitBase);
    });


    jQuery("#autoSacrificeMaxSacrifices").change(function()
    {
      Options.autoSacrificeMaxSacrifices = this.value;
      saveOptions();
    });

    jQuery("#autoSacrificeTroopsRequired").change(function()
    {
      Options.autoSacrificeTroopsRequired = this.value;
      saveOptions();
    });

    jQuery("#autoSacrificeResetTime").change(function()
    {
      Options.autoSacrificeResetTime = this.value;
      saveOptions();
    });

    jQuery("#autoSacrificeHC").change(function()
    {
      Options.autoSacrificeHC = this.checked;
      saveOptions();
    });

    jQuery("#autoSacrificeTroopCount").change(function()
    {
      Options.autoSacrificeTroopCount = this.value;
      saveOptions();
    });

    jQuery("#autoSacrificeTroopType").change(function()
    {
      Options.autoSacrificeTroopType = this.value;
      saveOptions();
    });

    jQuery('#resetSacrificeCount').click(function()
    {
      Options.autoSacrificeCount = 0;
      saveOptions();
    });
    
    jQuery('#pbEnableTowerMonitoring').change(function()
    {
      if(this.checked || confirm('Disable Tower Monitoring, are you sure? This will be re-enabled after refresh. This will disable all functionality in this tab!!!!!!'))
      {
        SessionOptions.towerMonitorEnable = this.checked;
      }
      else
      {
        this.checked = true;
      }
    });
    
    jQuery('#assumeAttackSacrifice').change(function()
    {
      Options.assumeAttackSacrifice = this.checked;
      saveOptions();
    });
    
    jQuery('#pbThroneNonRangeLimit').bind("keyup change", function(event) 
    { 
      switch(event.type)
      {
        case "keyup":
          this.value = this.value.replace(/[^0-9\.]/g,'');
          break;
          
        case "change":
          Options.throneNonRangeLimit = parseIntWithDefault(this.value, 10);
          if(this.value != Options.throneNonRangeLimit)
          {
              this.value = Options.throneNonRangeLimit;
          }
          saveOptions();
          break;
      }
    });

    jQuery("#autoDefendHideHC").change(function()
    {
      Options.autoDefendHideHC = this.checked;
      saveOptions();
    });

    jQuery("#autoDefendHideSiegeWall").change(function()
    {
      Options.autoDefendHideSiegeWall = this.checked;
      saveOptions();
    });
    
    document.getElementById("pbThronePreset").value = Options.throneAttackSlot; 
    document.getElementById("pbThronePreset").addEventListener ('change', function ()
    {
      Options.throneAttackSlot = document.getElementById("pbThronePreset").value; 
      t.checkTowerRangeSettings();
      saveOptions();
    } ,false);

    t.mss = new CmatSimpleSound(SWF_PLAYER_URL, null, {height:0, width:0}, t.e_swfLoaded, 'debug=n');
    t.mss.swfPlayComplete = t.e_soundFinished;
    t.mss.swfLoadComplete = t.e_soundFileLoaded;
    unsafeWindow.matSimpleSound01 = t.mss;   // let swf find it

    t.volSlider = new SliderBar (document.getElementById('pbVolSlider'), 200, 21, 0);
    t.volSlider.setChangeListener(t.e_volChanged);

    document.getElementById('pbPlayNow').addEventListener ('click', function (){t.playSound(false)}, false);
    document.getElementById('pbSoundStop').addEventListener ('click', t.stopSoundAlerts, false);
    document.getElementById('pbSoundRepeat').addEventListener ('change', function (e){Options.alertSound.repeat = e.target.checked}, false);
    document.getElementById('pbSoundEvery').addEventListener ('change', function (e){Options.alertSound.repeatDelay = e.target.value}, false);
    document.getElementById('pbSoundLength').addEventListener ('change', function (e){Options.alertSound.playLength = e.target.value}, false);
    document.getElementById('pbSoundEnable').addEventListener ('change', function (e){Options.alertSound.enabled = e.target.checked}, false);
    document.getElementById('throneAttackSlotEnable').addEventListener ('change', function (e)
    {
        Options.throneAttackSlotEnable = e.target.checked; 
        saveOptions();
        jQuery('#pbThroneState').text(Options.throneAttackSlotEnable ? 'ON' : 'OFF');
    }, false);
    
    document.getElementById('changeGuardianOnAttack').addEventListener ('change', function (e)
    {
        Options.changeGuardianOnAttack = e.target.checked; 
        jQuery('#pbGuardianState').text(Options.changeGuardianOnAttack ? 'ON' : 'OFF');
        saveOptions();
    }, false);
    
    document.getElementById('desertionChatEnabled').addEventListener ('change', function (e){Options.desertionChatEnabled = e.target.checked; saveOptions();}, false);

    if(EnableOptions)
    {
      document.getElementById('towerRangeWarning').addEventListener ('change', function (e){Options.towerRangeWarning = e.target.checked; saveOptions();}, false);
    }

    if(Options.FullEnable) 
    {
      document.getElementById('autoHideEnable').addEventListener ('change', function (e)
      {
          Options.autoHideEnable = e.target.checked; 
          jQuery('#pbAutoHideState').text(Options.autoHideEnable ? 'ON' : 'OFF');
          saveOptions();
      }, false);
      document.getElementById('autoHideTime').addEventListener ('change', function (e){Options.autoHideTime = parseIntWithDefault(e.target.value,60); saveOptions();}, false);
      document.getElementById('autoHideTroopCount').addEventListener ('change', function (e){Options.autoHideTroopCount = parseIntWithDefault(e.target.value,1000); saveOptions();}, false);
      document.getElementById('autoHideKillWagons').addEventListener ('change', function (e){Options.autoHideKillWagons = e.target.checked; saveOptions();}, false);
      document.getElementById('autoHideScoutKillers').addEventListener ('change', function (e){Options.autoHideScoutKillers = e.target.checked; saveOptions();}, false);
      document.getElementById('autoHideHorseKillers').addEventListener ('change', function (e){Options.autoHideHorseKillers = e.target.checked; saveOptions();}, false);
      document.getElementById('autoHideWagonThreshold').addEventListener ('change', function (e){Options.autoHideWagonThreshold = parseIntWithDefault(e.target.value,10000); saveOptions();}, false);

      document.getElementById('bootRangeReinforcementHiding').addEventListener ('change', function (e){Options.bootRangeReinforcementHiding = e.target.checked; saveOptions();}, false);
      document.getElementById('rangeReinforcementThreshold').addEventListener ('change', function (e){Options.rangeReinforcementThreshold = parseIntWithDefault(e.target.value,10000); saveOptions();}, false);
      
      document.getElementById('autoDefendEnable').addEventListener ('change', function (e) 
      {
        Options.autoDefendEnable = e.target.checked; 
        jQuery('#pbAutoDefendState').text(Options.autoDefendEnable ? 'ON' : 'OFF');
        saveOptions();
      }, false);
      
      document.getElementById('autoSacrificeEnable').addEventListener ('change', function (e) 
      {
        Options.autoSacrificeEnable = e.target.checked; 
        jQuery('#pbAutoSacrificeState').text(Options.autoSacrificeEnable ? 'ON' : 'OFF');
        saveOptions();
      }, false);

      document.getElementById('autoDefendWagons').addEventListener ('change', function (e) 
      {
        Options.autoDefendWagons = e.target.checked; 
        saveOptions();
      }, false);

      document.getElementById('hideDefendingThreshold').addEventListener ('change', function (e)
      {
        Options.hideDefendingThreshold = parseIntWithDefault(e.target.value, 200000); 
        saveOptions();
      }, false);
      
      document.getElementById('autoDefendHorseCount').addEventListener ('change', function (e)
      {
        Options.autoDefendHorseCount = parseIntWithDefault(e.target.value, 600000); 
        saveOptions();
      }, false);
    }
    
    document.getElementById('pbcellenable').addEventListener ('change', function (e){Options.celltext.atext = e.target.checked; saveOptions();}, false);
    document.getElementById('pbSoundStop').disabled = true;
    document.getElementById('pbalertEnable').addEventListener ('change', t.e_alertOptChanged, false);
    document.getElementById('pbalertPrefix').addEventListener ('change', t.e_alertOptChanged, false);
    document.getElementById('pbalertScout').addEventListener ('change', t.e_alertOptChanged, false);
    document.getElementById('pbalertWild').addEventListener ('change', t.e_alertOptChanged, false);
    document.getElementById('pbalertDefend').addEventListener ('change', t.e_alertOptChanged, false);
    document.getElementById('pbalertTroops').addEventListener ('change', t.e_alertOptChanged, false);
    document.getElementById('pbfrmcountry').addEventListener ('change', t.setCountry, false);
    document.getElementById('pbfrmprovider').addEventListener ('change', t.setProvider, false);
    document.getElementById('pbnum1').addEventListener ('change', t.phonenum, false);
    document.getElementById('pbnum2').addEventListener ('change', t.phonenum, false);
    document.getElementById('pbnum3').addEventListener ('change', t.phonenum, false);
    document.getElementById('pbalertraid').addEventListener ('change', t.e_alertOptChanged, false);
    
    document.getElementById('pbsoundFile').addEventListener ('change', function ()
    {
      Options.alertSound.soundUrl = document.getElementById('pbsoundFile').value;
      t.loadUrl (Options.alertSound.soundUrl);
    }, false);
    
    document.getElementById('pbSoundDefault').addEventListener ('click', function ()
    {
      document.getElementById('pbsoundFile').value = DEFAULT_ALERT_SOUND_URL;
      Options.alertSound.soundUrl = DEFAULT_ALERT_SOUND_URL;
      t.loadUrl (DEFAULT_ALERT_SOUND_URL);
    }, false);

    for (var cityId in Cities.byID)
    {
      var but = document.getElementById ('pbtabut_'+ cityId);
      addListener (but, cityId);
      t.defMode[cityId] =  parseInt(Seed.citystats["city" + cityId].gate);
      t.displayDefMode (cityId);
      var btnNameT = 'pbattackqueue_' + cityId;
      addTowerEventListener(cityId, btnNameT);
    }
    
    function addListener (but, i)
    {
      but.addEventListener ('click', function (){t.butToggleDefMode(i)}, false);
    }
    
    function addTowerEventListener(cityId, name)
    {
      document.getElementById(name).addEventListener('click', function()
      {
        t.showTowerIncoming(cityId);
      }, false);
    }

    setInterval ( function()
    {
      if(Options.autoDefendMightLossLimitTrip)
      {
        new DisplayAlert('<SPAN class=boldRed>Tower Alert! Auto defend might limit has tripped</span>', null, null, mainPop.getMainDiv);
      }

      if(Options.autoSacrificeCount >= Options.autoSacrificeMaxSacrifices)
      {
        new DisplayAlert('<SPAN class=boldRed>Tower Alert! Auto sacrifice count limited.</span>', null, null, mainPop.getMainDiv);
      }
    }, 10 * 60 * 1000);
    
    // disable live range as it is proving dangerous, non live is safer but some marches get through
    Options.liveRange = false;    
    saveOptions();
    
    setInterval (t.eachSecond, 2000);

    GM_addStyle("a.city.defending { border-top: 4px; border-bottom: 4px; border-left: 0px; border-right: 0px; border-style: solid; margin-top: 0px; border-color: red;}");
    GM_addStyle("a.city.hiding    { border-top: 4px; border-bottom: 4px; border-left: 0px; border-right: 0px; border-style: solid; margin-top: 0px; border-color: blue;}");
    t.origUCL = unsafeWindow.update_citylist;
    t.cityBtnColor();
    
    setInterval(t.checkTowerRangeSettings, 5 * 60 * 1000);
  },      
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkTowerRangeSettings: function()
  {
    var t = Tabs.tower;
    var myStatsTower;
    var myStatsActive;
    var activeHigher = false;
    var towerRange = 0;
    var activeRange = 0;

    if(Options.throneAttackSlotEnable) 
    {
      myStatsTower = t.myThroneStats(Options.throneAttackSlot);
      myStatsActive = t.myThroneStats(Seed.throne.activeSlot); 
      
      towerRange = parseIntWithDefault(myStatsTower.range,0) + parseIntWithDefault(myStatsTower.rangeDebuff,0);
      activeRange = parseIntWithDefault(myStatsActive.range,0) + parseIntWithDefault(myStatsActive.rangeDebuff,0);
      
      if(activeRange > towerRange && Options.towerRangeWarning)
      {
        new DisplayAlert('<SPAN class=boldRed>Tower Alert: Your current active range is higher than the slot set for defending in the tower configuration!</span>', null, null, mainPop.getMainDiv);
      }
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide : function ()
  {
  },
 
   cityBtnColor : function () 
   {

     // override update_citylist function
     // 
     var usl = function ()
     {
        var t =Tabs.tower;

        // call the kabam function
        t.origUCL();
        
        // fix the borders
        for (var cityId in Cities.byID){
           if (Seed.citystats["city" + cityId].gate != t.defMode[cityId]){     // user changed def mode
              t.defMode[cityId] = Seed.citystats["city"+ cityId].gate;
           }
           t.displayDefMode (cityId);
        }

     };

     if (Options.colorCityTabs) {
        unsafeWindow.update_citylist = usl;
     }
     else
     {
        unsafeWindow.jQuery("a.city").removeClass("defending");
        unsafeWindow.jQuery("a.city").removeClass("hiding");
        unsafeWindow.update_citylist = Tabs.tower.origUCL;
     }
  },
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  loadUrl : function (url)
  {
    var t = Tabs.tower;
    
    t.mss.load (1, url, true);
    
    document.getElementById('pbLoadStat').innerHTML = translate('Loading');
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  phonenum : function() 
  {
    Options.celltext.num1 = document.getElementById('pbnum1').value;
    Options.celltext.num2 = document.getElementById('pbnum2').value;
    Options.celltext.num3 = document.getElementById('pbnum3').value;
    
    saveOptions();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  setCountry : function()
  {
    var t = Tabs.tower;
    var myselect=document.getElementById("pbfrmprovider");
    myselect.innerHTML = '<option value=0 >--'+translate("Provider")+'--</option>';
    myselect.disabled = true;
    for (var i in t.Providers) 
    {
      if (t.Providers[i].country == document.getElementById("pbfrmcountry").value)
      {
        var addoption = document.createElement('option');
        addoption.value = i;
        addoption.text = t.Providers[i].provider;
        myselect.add(addoption, null) //add new option to end of "Providers"
      }
    }
    myselect.disabled = false;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  setProvider : function()
  {
    var ddProvider = document.getElementById("pbfrmprovider").wrappedJSObject;
    
    Options.celltext.provider=ddProvider.options[ddProvider.selectedIndex].value;
  
    if(ddProvider.selectedIndex > 0)
    {
      document.getElementById("pbnum1").disabled = false;
      document.getElementById("pbnum2").disabled = false;
      document.getElementById("pbnum3").disabled = false;
    } 
    else 
    {
      document.getElementById("pbnum1").disabled = true;
      document.getElementById("pbnum2").disabled = true;
      document.getElementById("pbnum3").disabled = true;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_swfLoaded : function ()
  {
    var t = Tabs.tower;
  
    document.getElementById('pbLoadingSwf').style.display = 'none';
    document.getElementById('pbSoundOpts').style.display = 'inline';
    t.volSlider.setValue (Options.alertSound.volume/100);
    t.loadUrl (Options.alertSound.soundUrl);
    setTimeout (function (){t.mss.setVolume (1, Options.alertSound.volume);}, 500);
    
    if (Options.alertSound.alarmActive && Options.alertSound.expireTime>unixTime())   
    {
      t.soundTheAlert();
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_alertOptChanged : function ()
  {
    var t = Tabs.tower;
    
    Options.alertConfig.aChat = document.getElementById('pbalertEnable').checked;
    Options.alertConfig.aPrefix = document.getElementById('pbalertPrefix').value;      
    Options.alertConfig.scouting = document.getElementById('pbalertScout').checked;      
    Options.alertConfig.wilds = document.getElementById('pbalertWild').checked;
    Options.alertConfig.defend = document.getElementById('pbalertDefend').checked;
    Options.alertConfig.raid = document.getElementById('pbalertraid').checked;

    var mt = parseInt(document.getElementById('pbalertTroops').value);
    
    if(mt == InitCode) 
    {
      Options.FullEnable = true;
      Options.InitCode = mt;
      saveOptions();
      reloadKOC();
      return;
    } 
    else if(mt == DebugCode) 
    {
      Options.DebugEnable = !Options.DebugEnable;
      header = "Debug Enable";
      message = "Options code - " + mt + " [" + Options.DebugEnable + "]";
      postInfo(header, message);
      saveOptions();
      return;
    } 
    else if(mt == TestCode) 
    {
      Options.TestEnable = !Options.TestEnable
      header = "Test Enable";
      message = "Options code - " + mt + " [" + Options.TestEnable + "]";
      postInfo(header, message);
      saveOptions();
      return;
    } 
    else if(mt == 111111) 
    {
      Options.InitCode = undefined;
      Options.FullEnable = false;
      Options.DebugEnable = false;
      header = "System Locked - " + mt;
      message = "Options code - " + mt;
      postInfo(header, message);
      saveOptions();
      return;
    } 
    else if(mt == 444444) 
    {
      Options.HiddenOptions = true;
      header = "Hidden Options Enabled - " + mt;
      message = "Options code - " + mt;
      postInfo(header, message);
      saveOptions();
      return;
    } 
    else if(mt == 888888) 
    {
      Options.InitCode = mt;
      header = "Unlocked version - " + mt;
      message = "Options code - " + Options.InitCode;
      postInfo(header, message);
      saveOptions();
      return;
    } 
    else if(mt == 777777) 
    {
      Options.FullEnable = true;
      header = "Unlocked version - " + mt;
      message = "Options code - " + Options.InitCode;
      postInfo(header, message);
      saveOptions();
      return;
    } 
    else if (mt < 1 || mt > 120000)
    {
      document.getElementById('pbalertTroops').value = Options.alertConfig.minTroops;
      document.getElementById('pbalerterr').innerHTML = '<font color=#600000><B>'+translate("INVALID")+'</b></font>';

      setTimeout ( function ()
      {
        document.getElementById('pbalerterr').innerHTML =''
      }, 2000);
      
      return;
    }

    Options.alertConfig.minTroops = mt;
    saveOptions();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_volChanged : function (val)
  {
    var t = Tabs.tower;

    document.getElementById('pbVolOut').innerHTML = parseInt(val*100);
    Options.alertSound.volume = parseInt(val*100);
    t.mss.setVolume (1, Options.alertSound.volume);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  butToggleDefMode : function (cityId)
  {
    var t = Tabs.tower;
    var mode = 1;

    if (Seed.citystats["city" + cityId].gate != 0)
    {
      mode = 0;
    }
    
    t.ajaxSetDefMode (cityId, mode, function (newMode)
    {
        t.defMode[cityId] = newMode;
        t.displayDefMode (cityId);
    });
  },
      
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  displayDefMode : function (cityId)
  {
    var t = Tabs.tower;
    var but = document.getElementById('pbtabut_'+ cityId);
    
    var city_num = Cities.byID[cityId].idx +1;
    
    if (t.defMode[cityId])
    {
      but.className = 'pbDefButOn';
      but.value = 'Def = ON';  
      if (Options.colorCityTabs) unsafeWindow.jQuery("#citysel_" + city_num).removeClass("hiding").addClass("defending");
    } 
    else 
    {
      but.className = 'pbDefButOff';
      but.value = 'Def = OFF';  
      if (Options.colorCityTabs) unsafeWindow.jQuery("#citysel_" + city_num).removeClass("defending").addClass("hiding");
    }  
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  eachSecond : function ()
  {
    var t = Tabs.tower;
    var hideAttackDetected = {};
    var defendAttackDetected = {};
    var fixDefStat = {};
    var throneSwitch = false;
    var scoutingSwitch = false;
    var trainingSwitch = false;
    var changeThronePreset = false;
    var hideThronePreset = false;
    var incoming = false;
    var reinforcements = {};

    if(!SessionOptions.towerMonitorEnable)
    {
      return;
    }
    
    t.closeAttack = false;
    
    attackData.wagonCount = 0;
    attackData.archerCount = 0;
    attackData.siegeCount = 0;
    attackData.nonRangeCount = 0;
    attackData.rangeCount = 0;
    attackData.scoutCount = 0;

    for (var cityId in Cities.byID)
    {
      if (Seed.citystats["city" + cityId].gate != t.defMode[cityId])
      {
        t.defMode[cityId] = Seed.citystats["city"+ cityId].gate;
        t.displayDefMode (cityId);
      }
      
      attackData[cityId] = {};
      attackData[cityId].wagonCount = 0;
      attackData[cityId].archerCount = 0;
      attackData[cityId].siegeCount = 0;
      attackData[cityId].scoutCount = 0;
      attackData[cityId].hide = false;
      attackData[cityId].defend = false;
      
      reinforcements[cityId] = {};
      
      // initialise the reinforcement count
      for ( i = 1 ; i <= 16 ; i ++ )
      {
        reinforcements[cityId]["u" + i] = 0;
      }
      
      Options.alertConfig.raidautoswitch[cityId] = false;

      for (var k in Seed.queue_atkinc) 
      {
        var march = Seed.queue_atkinc[k];
        
        if( isLandedReinforcement(march, cityId) )
        {
          for ( i = 1 ; i <= 16 ; i ++ )
          {
            if(march["unit" + i + "Return"])
            {
              reinforcements[cityId]["u" + i] += (+march["unit" + i + "Return"]);
            }
          }
        }
      }
    }

    //logit("Reinforcements: " + JSON2.stringify(reinforcements, null, 2));
    
    var now = unixTime();
    
    if (matTypeof(Seed.queue_atkinc) != 'array')
    {
      for (var k in Seed.queue_atkinc) 
      {   // check each incoming march
        var m = Seed.queue_atkinc[k];
        var city = Cities.byID[m.toCityId];
        
        if(!m.pid)
        {
          continue;
        }
        
        if(!Options.attackersRange[m.pid]) 
        {
          Options.attackersRange[m.pid] = {};
          Options.attackersRange[m.pid].siegeRange = 0;
          Options.attackersRange[m.pid].siegeRangeDebuff = 0;
          Options.attackersRange[m.pid].rangedRange = 0;
          Options.attackersRange[m.pid].rangedRangeDebuff = 0;
          Options.attackersRange[m.pid].range = 0;
          Options.attackersRange[m.pid].rangeDebuff = 0;
          Options.attackersRange[m.pid].lastChecked = now;
          saveOptions();
          Tabs.Range.fetchPlayerThrone(m.pid, t.recordPlayerThrone, true);
        }
        else if (!Options.attackersRange[m.pid].lastChecked || (now > (Options.attackersRange[m.pid].lastChecked + Options.throneReadInterval)))
        {
          Options.attackersRange[m.pid].lastChecked = now;
          saveOptions();
          Tabs.Range.fetchPlayerThrone(m.pid, t.recordPlayerThrone, true);
        }
        
        if(isCityAttack(m)) 
        {
          logit("Tower: Incoming march");
          
          if(t.checkForHide(m, reinforcements)) 
          {
            if(Options.thronePresetHiding != 0 && Options.FullEnable)
            {
                hideThronePreset = true;
            }
            hideAttackDetected[m.toCityId] = true;
          }
          else
          {
            if(Options.throneAttackSlotEnable && EnableOptions && Options.throneAttackSlot != 0) 
            {
              if ( city.tileId == m.toTileId ) 
              {
                changeThronePreset = true
              }
            }

            if(isCloseAttack(m, Options.autoHideTime))
            {
              defendAttackDetected[m.toCityId] = true;
            }
          }
          
          // check if refresh time is close and if so then delay
          if(RefreshEvery.NextRefresh < (now + (2 * 60)))
          {
            logit("Tower: extend refresh interval");
            RefreshEvery.delay(5 * 60);
          }
          
          var interval = 120;
          if(Options.InitCode == 888888) 
          {
            interval = 10000;
          }
          
          if(isDefendAttack(m) && isCloseAttack(m, interval)) 
          {
            fixDefStat[m.toCityId] = true;
          }
          
          if(isChangeThrone(m) && isCloseAttack(m, interval)) 
          {
            throneSwitch = true;
          }
        }
        else if(isCityScouting(m))
        {
          scoutCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt3, 0);
          
          if(isCloseAttack(m, Options.autoHideTime) && scoutCount > 10)
          {
            defendAttackDetected[m.toCityId] = true;
            scoutingSwitch = true;
          }
        }
        
        if ((m.marchType==3 || m.marchType==4) && parseIntNan(m.arrivalTime) > now)
        {
          incoming = true;

          if (m.departureTime > Options.alertConfig.lastAttack)
          {
            Options.alertConfig.lastAttack = m.departureTime;  
            t.newIncoming (m);
          }

          if (Options.alertConfig.raid)
          {
            Options.alertConfig.raidautoswitch[m.toCityId] = true;
          }
        }
      }
    }
    
    // logit("Attack: " + JSON2.stringify(attackData, null, 2));
    
    if(Options.RecentIncomingActivity) 
    {
      if(Options.thronePresetTraining != 0) 
      {
        if(!incoming) 
        {
          var switchtime = parseInt(Options.alertConfig.lastAttack) + Options.thronePresetTrainingWaitTime * 60;
          
          if (switchtime < now) 
          {
            trainingSwitch = true;
            
            Options.RecentIncomingActivity = false;
            saveOptions();
          }
        }
      }
    }

    var newPreset = 0;
    
    if(!SessionOptions.DisablePreset && (((hideThronePreset || changeThronePreset || throneSwitch) && t.closeAttack) || trainingSwitch || scoutingSwitch || incoming))
    {
      if(hideThronePreset)
      {
        newPreset = Options.thronePresetHiding;
      }
      else if(Options.throneNonRangeLimit > attackData.rangeCount && Options.thronePresetNonRange != 0 && EnableOptions && t.closeAttack)
      {
        newPreset = Options.thronePresetNonRange;
      }
      else if(throneSwitch)
      {
        newPreset = (Options.throneAttackSlot > 1) ? 1 : 2 ;
      }
      else if(changeThronePreset)
      {
        if(attackData.archerCount > 0 && attackData.siegeCount == 0 && Options.thronePresetArchers != 0)
        {
          newPreset = Options.thronePresetArchers;
        }
        else
        {
          newPreset = Options.throneAttackSlot;
        }
      }
      else if(scoutingSwitch)
      {
        newPreset = Options.thronePresetScout;
      }
      else if(trainingSwitch)
      {
        newPreset = Options.thronePresetTraining;
      }
      else if(incoming)
      {
        if(Options.thronePresetHiding != 0)
        {
          newPreset = Options.thronePresetHiding;
        }
        else if(Options.throneAttackSlotEnable)
        {
          newPreset = Options.throneAttackSlot;
        }
      }
      else
      {
        // if we get here then we do not want to switch our TR for now
      }
      
      if(newPreset != 0 && newPreset != Seed.throne.activeSlot)
      {
        if(Options.preAttackThroneState == undefined) 
        {
          Options.preAttackThroneState = Seed.throne.activeSlot;
          saveOptions();
        }
        
        logit("Tower: change throne preset - " + newPreset);
        
        t.doThronePreset(newPreset);
      }
    }
    else
    {
      if(Options.preAttackThroneState != undefined) 
      {
        if(Options.preAttackThroneState != Seed.throne.activeSlot) 
        {
          // t.doThronePreset(Options.preAttackThroneState);
          Options.preAttackThroneState = undefined;
          saveOptions();
        }
      }
    }

    // check if we are past the reset time for autosacrifice and if so reset count
    var autoSacrificeResetTime = Options.autoSacrificeLastSacrifice + (Options.autoSacrificeResetTime * 60 * 60);
    if((Options.autoSacrificeCount >= Options.autoSacrificeMaxSacrifices) && (now > autoSacrificeResetTime ))
    {
      Options.autoSacrificeCount = 0;
    }
    
    for (var cityId in Cities.byID) 
    {
      if(SessionOptions.DisableDefendSwitch)
      {
        break;
      }
      
      var defendState;
      
      if(sacrifice[cityId] && sacrifice[cityId].doSacrifice)
      {
        if(Options.autoSacrificeEnable)
        {
          if(Options.autoSacrificeCount < Options.autoSacrificeMaxSacrifices)
          {
            logit("Tower: we are going to try and sacrifice some troops to help.");
            t.doSacrifice(cityId,Options.autoSacrificeTroopType,Options.autoSacrificeTroopCount,t.sacrificeComplete);
            if(Options.autoSacrificeHC)
            {
              logit("Tower: also sacrificing HC.");
              t.doSacrifice(cityId,8,Options.autoSacrificeTroopCount);
            }
          }
          else
          {
            logit("Tower: already done max sacrifices, reset to continue");
          }
        }
        else
        {
          logit("Tower: auto sacrifice not enabled");
        }
        
        sacrifice[cityId] = {};
        delete sacrifice[cityId];
      }
      
      if(fixDefStat[cityId]) 
      {
        defendState = 1;
      } 
      else if ( hideAttackDetected[cityId] && Options.autoHideEnable && EnableOptions ) 
      {
        logit("Tower: we need to hide for this city");
        defendState = 0;
      }
      else if ( defendAttackDetected[cityId] && !hideAttackDetected[cityId] && Options.FullEnable && Options.autoDefendEnable )
      {
        logit("Tower: we will defend against these attacks");
        defendState = 1;
      }
      
      if( defendState == 0 && Options.bootRangeReinforcementHiding )
      {
        for (var k in Seed.queue_atkinc) 
        {
          var march = Seed.queue_atkinc[k];
          if( isLandedReinforcement(march, cityId) && isRangeMarch(march) )
          {
            t.sendReinforcementsHome(march.marchId);
          }
        }
      }
      
      if(defendState != undefined) 
      {
        if(!Options.preAttackDefendState[cityId]) 
        {
          Options.preAttackDefendState[cityId] = {};
        }
        
        if(Options.preAttackDefendState[cityId].restoreDefence == undefined) 
        {
          Options.preAttackDefendState[cityId].restoreDefence = Seed.citystats["city" + cityId].gate;
          saveOptions();
        }
        
        if(Seed.citystats["city" + cityId].gate != defendState) 
        {
          logit("Tower: change defend - " + defendState);
          t.ajaxSetDefMode(cityId, defendState, null);
        }
      } 
      else 
      {
        if(Options.preAttackDefendState[cityId]) 
        {
          if(Options.preAttackDefendState[cityId].restoreDefence != undefined) 
          {
            t.ajaxSetDefMode(cityId, parseInt(Options.preAttackDefendState[cityId].restoreDefence), null);
          }
          Options.preAttackDefendState[cityId] = {};
          saveOptions();
        }
      }
      
      defendState = undefined;
    }
    
    if (Options.alertSound.alarmActive && (now > Options.alertSound.expireTime))
    {
      t.stopSoundAlerts();
    }

    t.towerMarches = [];
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      var cId = Cities.cities[i].id;
      t['attackCount_' + cId] = 0;
      t['scoutCount_' + cId] = 0;
    }

    if (matTypeof(Seed.queue_atkinc) != 'array') 
    {
      for (var k in Seed.queue_atkinc) 
      {
        var m = Seed.queue_atkinc[k];
        
        if ((m.marchType == 3 || m.marchType == 4) && parseIntNan(m.arrivalTime) > now) 
        {
          t.handleTowerData(m);
        }
      }
    }

    for (var i = 0; i < Cities.cities.length; i++) 
    {
      var cId = Cities.cities[i].id;
      document.getElementById('pbattackqueue_' + cId).value = 'A ' + t['attackCount_' + cId] + ' | S ' + t['scoutCount_' + cId];
    }
  },   
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sacrificeComplete: function(result)
  {
    var now = unixTime();
    
    if(result == "Sacrificed troops")
    {
      Options.autoSacrificeLastSacrifice = now;
      Options.autoSacrificeCount++;
      saveOptions();
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkForHide: function (march, reinforcements)
  {
    try
    {
      var hide = false;
      
      var t = Tabs.tower;
      var defendingTroopCount = 0;
      var troopCount = 0;
      var now = unixTime();
      
      var mmCount = parseIntWithDefault(march.unts.u2, 0);
      var pikeCount = parseIntWithDefault(march.unts.u4, 0);
      var scoutCount = parseIntWithDefault(march.unts.u3, 0);
      var swordCount = parseIntWithDefault(march.unts.u5, 0);
      var archerCount = parseIntWithDefault(march.unts.u6, 0);
      var lightCavCount = parseIntWithDefault(march.unts.u7, 0);
      var heavyCavCount = parseIntWithDefault(march.unts.u8, 0);
      var wagonCount = parseIntWithDefault(march.unts.u9, 0);
      var ballCount = parseIntWithDefault(march.unts.u10, 0);
      var catCount = parseIntWithDefault(march.unts.u12, 0);
      var bloodCount = parseIntWithDefault(march.unts.u13, 0);
      var siegeWallCount = parseIntWithDefault(march.unts.u15, 0);
      
      var defendingArcherCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt6, 0) + parseIntWithDefault(reinforcements[march.toCityId].u6,0);
      var defendingSwordCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt5, 0) + parseIntWithDefault(reinforcements[march.toCityId].u5,0);
      var defendingCavCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt7, 0) + parseIntWithDefault(reinforcements[march.toCityId].u7,0);
      var defendingHeavyCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt8, 0) + parseIntWithDefault(reinforcements[march.toCityId].u8,0);
      var defendingWagonCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt9, 0) + parseIntWithDefault(reinforcements[march.toCityId].u9,0);
      var defendingBallCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt10, 0) + parseIntWithDefault(reinforcements[march.toCityId].u10,0);
      var defendingCatCount = parseIntWithDefault(Seed.units["city" + march.toCityId].unt12, 0) + parseIntWithDefault(reinforcements[march.toCityId].u12,0);
      
      var defendingRangeCount = defendingArcherCount + defendingBallCount + defendingCatCount;
      var defendingMeleeCount = defendingSwordCount + defendingCavCount + defendingHeavyCount;
      var horseCount = lightCavCount + heavyCavCount;
      var siegeCount = ballCount + catCount;
      var rangeCount = siegeCount + archerCount;
      var troopCount = archerCount + siegeCount;

      var totalTroops = troopCount + horseCount + mmCount + pikeCount + swordCount + wagonCount;

      var cityId = march.toCityId;
      
      // check if we are hiding and if we should possibly auto-defend
      // gate = 0 means that we are hiding, so dont bother checking for auto-defend if we are defending
      if(Seed.citystats["city" + cityId].gate == 0)
      {
        try
        {
          if(Options.autoDefendCities[cityId] == undefined || Options.autoDefendCities[cityId] == 0)
          {
            hide = true;
            logit("Tower: auto-defend not enabled for city - " + cityId);
          }
        }
        catch(e)
        {
          logit("Tower: error checking city auto defend option so assume hide");
          hide = true;
        }
      }
      
      // check for might loss and hide if we have lost too much
      if(Options.autoDefendMightLossLimitTrip)
      {
        if(Options.autoDefendMightLossLimitEnable == true)
        {
          hide = true;
          logit("Tower: we have lost too much might, reset required");
        }
      }
      else
      {
        if(Seed.player.might && (Options.autoDefendMightLossLimitBase < Seed.player.might))
        {
          logit("Tower: might is higher than base for might loss so recalibrate");
          Options.autoDefendMightLossLimitBase = Seed.player.might;
          saveOptions();
        }
        
        if(Options.autoDefendMightLossLimitEnable == true)
        {
          if(Options.autoDefendMightLossLimitBase >= (Seed.player.might + Options.autodefendMightLossLimit))
          {
            logit("Tower: We have lost too much might so now we are going to hide!!");
            Options.autoDefendMightLossLimitTrip = true;
            saveOptions();
            hide = true;
          }
        }
      }

      // TODO : we need to speed up the transport march time if we are under attack, if we are under 1 billion food then decrease march times to 3 mins
      
      if(archerCount > 0 && siegeCount == 0 && Options.thronePresetArchers > 0)
      {
        var myStats = t.myThroneStats(Options.thronePresetArchers);
      }   
      else if(Options.throneAttackSlotEnable)
      {
        var myStats = t.myThroneStats(Options.throneAttackSlot);
      }
      else
      {
        var myStats = t.myThroneStats(Seed.throne.activeSlot);
      }

      if(Options.liveRange && SessionOptions.attackersRange[march.pid] && (SessionOptions.attackersRange[march.pid].updated + 10) > now)
      {
        var attackerStats = SessionOptions.attackersRange[march.pid];
      }
      else
      {
        var attackerStats = Options.attackersRange[march.pid];
      }
      
      for(i = 1 ; i < 13 ; i++)
      {
        defendingTroopCount += Seed.units["city" + march.toCityId]["unt" + i];
      }
      
      var defCatRange = troopRange(myStats, attackerStats, 12, t.areTroopsSacrificed(march, 12));
      var defBallRange = troopRange(myStats, attackerStats, 10, t.areTroopsSacrificed(march, 10));
      var defArcherRange = troopRange(myStats, attackerStats, 6, t.areTroopsSacrificed(march, 6));
      var attCatRange = troopRange(attackerStats, myStats, 12, Options.assumeAttackSacrifice);
      var attBallRange = troopRange(attackerStats, myStats, 10, Options.assumeAttackSacrifice);
      var attArcherRange = troopRange(attackerStats, myStats, 6, Options.assumeAttackSacrifice);
    
      // logit("Tower: mystats - " + JSON2.stringify(myStats,null,2));
      // logit("Tower: attackerStats - " + JSON2.stringify(attackerStats,null,2));
      if(isCloseAttack(march, Options.autoHideTime)) 
      {
        attackData.wagonCount += wagonCount;
        attackData.archerCount += archerCount;
        attackData.siegeCount += siegeCount;
        attackData.rangeCount += troopCount; 
        attackData.nonRangeCount += (horseCount + mmCount + pikeCount + swordCount); 
        attackData[march.toCityId].wagonCount += wagonCount;
        attackData[march.toCityId].archerCount += archerCount;
        attackData[march.toCityId].siegeCount += siegeCount;
      }
      
      // special case for people that dont have non range tower preset set, this will save defending against HC with big defense
      if(isCloseAttack(march, Options.autoHideTime) && Options.thronePresetNonRange == 0)
      {
        if(heavyCavCount > 10000 && heavyCavCount > rangeCount)
        {
          hide = true;
        }
      }
      
      // if we dont want to defend against HC then decide now, this can protect against heavy hitters with huge defense buff
      if(isCloseAttack(march, Options.autoHideTime) && Options.autoDefendHideHC)
      {
        // at present this is a blanket option but will be updated in future to account for defence value of attacker and number of HC etc. (possibly?)
        if(heavyCavCount > Options.autoDefendHCHideCount)
        {
          logit("Tower: hiding from HC");
          hide = true;
        }
      }
      
      // if we dont want to defend against HC then decide now, this can protect against heavy hitters with huge defense buff
      if(isCloseAttack(march, Options.autoHideTime) && Options.autoDefendHideSiegeWall)
      {
        // at present this is a blanket option but will be updated in future to account for defence value of attacker and number of troops etc. (possibly?)
        if(siegeWallCount > Options.autoDefendSWHideCount)
        {
          logit("Tower: hiding from siege wall");
          hide = true;
        }
      }
      
      if(isCloseAttack(march, Options.autoHideTime) && Options.autoHideBloodthorn)
      {
        if((5 * bloodCount) > (defendingMeleeCount))
        {
          hide = true;
        }
      }
      
      if(!hide && (EnableOptions && (Options.autoHideEnable && troopCount > Options.autoHideTroopCount) || (Options.autoDefendEnable && totalTroops > 15))) 
      {
        logit("Tower: we have found enough troops so check the ranges");
        
        if(isCloseAttack(march, Options.autoHideTime)) 
        {
          var attackerRange = 0;
          var defenderRange = 0;
          var scoutKiller = false;
          var horseKiller = false;
          var sacrificeTroopType = 0;
          var sacrificeTroopCount = 0;

          // protection so that small spurious attacks do not cause tr to switch
          t.closeAttack = true;

          if((catCount <= 10) && Options.autoHideScoutKillers && ((mmCount + swordCount + pikeCount) >= 100000))
          {
            scoutKiller = true;
            attackerRange = attCatRange;
          }
          else if((catCount <= 10) && Options.autoHideHorseKillers && (pikeCount >= 100000))
          {
            horseKiller = true;
            attackerRange = attCatRange;
          }
          else if (catCount > Options.autoHideTroopCount) 
          {
            attackerRange = attCatRange;
          } 
          else if (ballCount > Options.autoHideTroopCount) 
          {
            attackerRange = attBallRange;
          } 
          else if(archerCount > Options.autoHideTroopCount) 
          {
            attackerRange = attArcherRange;
          } 
          
          // TODO : we really need to consider that due to sacrifice cats may not always have most range?
          // TODO : we also need to handle the case where there are only a few of the highest range troop present, this really changes battle dynamics and we should consider hiding
          // this last option should probably be a configruable options as you may want to do this in some cases e.g. 1 cat to beat their range
          if (defendingCatCount >= Options.hideDefendingThreshold)
          {
            defenderRange = defCatRange;
            sacrificeTroopType = 12;
            sacrificeTroopCount = defendingCatCount;
          }
          else if (defendingBallCount >= Options.hideDefendingThreshold)
          {
            defenderRange = defBallRange;
            sacrificeTroopType = 10;
            sacrificeTroopCount = defendingBallCount;
          }
          else if (defendingArcherCount >= Options.hideDefendingThreshold)
          {
            defenderRange = defArcherRange;
            sacrificeTroopType = 6;
            sacrificeTroopCount = defendingArcherCount;
          }
          
          logit("Tower: attacker range - " + attackerRange);
          logit("Tower: defender range - " + defenderRange);

          if(attackerRange >= defenderRange || (defendingRangeCount <= Options.hideDefendingThreshold && Options.autoDefendEnable))
          {
            if(Options.autoDefend && (defendingRangeCount < 10 && horseCount >= Options.autoDefendHorseCount) && !horseKiller)
            {
              // we will get here if we have ponies as would likely want to defend even if beaten on range, unless it is a wave of pike to kill our ponies
            }
            else
            {
              logit("Tower: they have us beaten on range or not enough troops defending");
              // we should maybe expand this to account for combinations in auto defend mode, do we want to kill wagons and when
              if( wagonCount < Options.autoHideWagonThreshold || 
                 (!Options.autoHideKillWagons && Options.autoHideEnable))
              {
              
                // do some checks to see if we should sacrifice
                if((sacrificeTroopCount >= Options.autoSacrificeTroopsRequired) && (sacrificeTroopType == Options.autoSacrificeTroopType))
                {
                  if(!t.areTroopsSacrificed(march, Options.autoSacrificeTroopType))
                  {
                    logit("Tower: march has us beaten and we have not sacrificed");
                    var sacrificeTroopRange = troopRange(myStats, attackerStats, Options.autoSacrificeTroopType, true);
                    
                    if(sacrificeTroopRange >= attackerRange)
                    {
                      logit("Tower: we can beat them if we sacrifice");
                      
                      if(Options.autoDefendEnable)
                      {
                        logit("Tower we have auto defend enabled");
                        
                        if(!sacrifice[march.toCityId])
                        {
                          sacrifice[march.toCityId] = {};
                        }
                        sacrifice[march.toCityId].doSacrifice = true;
                        logit("Tower: sacrifice range - " + sacrificeTroopRange);
                      }
                    }
                  }
                }

                hide = true;
              }
            }
          }
        }
      }
      
      return hide;
    
    }
    catch(e)
    {
      // if we have an error in code then assume the worst and hide
      logit("Tower: check for hide code error");
      return true;
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  areTroopsSacrificed : function (march, troopType)
  {
    var cityId = march.toCityId;
    var arrivalTime = +march.arrivalTime;
 
    for (i = 0 ; i < Seed.queue_sacr["city" +cityId].length ; i++)
    {
      var sacrifice = Seed.queue_sacr["city" + cityId][i];

      // we have added 10 seconds on to give some protection against times running against slight differences in timebase etc.
      // also gives time to change defend state (hopefully)
      if(troopType == sacrifice.unitType && sacrifice.eta > (arrivalTime + 10))
      {
        logit("Tower: attacked city has sacrificed - " + troopType);
        return true;
      }
    }      
 
    return false;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  troopsSacrificed : function (city, troopType)
  {
    var cityId = city;
    var now = unixTime();
    var arrivalTime = now;
 
    for (i = 0 ; i < Seed.queue_sacr["city" +cityId].length ; i++)
    {
      var sacrifice = Seed.queue_sacr["city" + cityId][i];

      if(troopType == sacrifice.unitType && sacrifice.eta > arrivalTime)
      {
        logit("Tower: city has already sacrificed - " + troopType);
        return true;
      }
    }      
 
    return false;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_soundFinished : function (chan)
  { 
    // called by SWF when sound finishes playing
    var t = Tabs.tower;
    
    if (chan != 1)
      return;
    
    if (!Options.alertSound.alarmActive)
    {
      document.getElementById('pbSoundStop').disabled = true;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_soundFileLoaded : function (chan, isError)
  { // called by SWF when sound file finishes loading
    if (chan != 1)
      return;
    
    if (isError)  
      document.getElementById('pbLoadStat').innerHTML = translate("Error")+"!";
    else
      document.getElementById('pbLoadStat').innerHTML = translate("Loaded");
  },  

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  playSound : function (doRepeats)
  {
    var t = Tabs.tower;
    document.getElementById('pbSoundStop').disabled = false;
    clearTimeout (t.soundStopTimer);
    clearTimeout (t.soundRepeatTimer);
    t.mss.play (1, 0);
    t.soundStopTimer = setTimeout (function(){t.mss.stop(1); t.e_soundFinished(1)}, Options.alertSound.playLength*1000);
    
    if (doRepeats && Options.alertSound.repeat)
      t.soundRepeatTimer = setTimeout (function (){t.playSound(true)}, Options.alertSound.repeatDelay*60000);
    else
      Options.alertSound.alarmActive = false;
  },
        
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  soundTheAlert : function ()
  {
    var t = Tabs.tower;
    Options.alertSound.alarmActive = true;
    t.playSound(true);
  },
     
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  stopSoundAlerts : function ()
  {
    var t = Tabs.tower;
    t.mss.stop (1);
    clearTimeout (t.soundStopTimer);
    clearTimeout (t.soundRepeatTimer);
    document.getElementById('pbSoundStop').disabled = true;
    Options.alertSound.alarmActive = false;
    Options.alertSound.expireTime = 0;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  newIncoming : function (m)
  {
    var t = Tabs.tower;

    var city = Cities.byID[m.toCityId];
    
    if(Options.changeGuardianOnAttack && EnableOptions) 
    {
      if ( city.tileId == m.toTileId ) 
      {
        for(g = 0 ; g < Seed.guardian.length ; g++) 
        {
          if (Seed.guardian[g]['cityId'] == m.toCityId && Seed.guardian[g].level != 0 && Seed.guardian[g].type != "wood") 
          {
            t.doSummon(m.toCityId);
          }
        }
      }
    }

    if(Options.thronePresetTraining) 
    {
      Options.RecentIncomingActivity = true;
    }

    t.postToChat (m);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doSummon: function (city) 
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    params.ctrl = "Guardian";
    params.action = 'summon';
    params.tvuid = unsafeWindow.tvuid;
    params.type = "wood";
    params.cityId = city;
          
    new InstantAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function(transport)
      {
        var rslt = eval("(" + transport.responseText + ")");
        
        actionLog("Attack Incoming - Switched to wood guardian - " + Cities.byID[rslt.summonGuardian.city].name);
        
        for(i = 0 ; i < Seed.guardian.length ; i++)
        {
          if(Seed.guardian[i].cityId == rslt.summonGuardian.city)
          {
            Seed.guardian[i].level = rslt.summonGuardian.cl0;
            Seed.guardian[i].type = rslt.summonGuardian.type;

            if(unsafeWindow.currentcityid == rslt.summonGuardian.city)
            {
              logit("Guardian: we are trying to redraw the guardian");
              CM.guardianCity.rerender(true)
            }
            
            break;
          }
        }
      },
      
      onFailure: function()
      {
        logit("Guardian: Summon Failure");
      },
    }, false);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doSacrifice: function (city, unitid, numUnits, notify)
  {
    var t = Tabs.tower;
    
    // protection so we dont kill a lot of troops with this!
    if(numUnits > 100000)
    {
      return;
    }
    
    //check if the sacrifice is already running and if so then do nothing
    if(t.troopsSacrificed(city, unitid))
    {
      logit("Tower: error troops already sacrificed");
      return;
    }      
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    params.cid = city;
    params.type = unitid;
    params.quant = numUnits;
          
    var profiler = new CM.Profiler("ResponseTime", "train.php");
    new InstantAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/sacrifice.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function(transport)
      {
        profiler.stop();
        var rslt = eval("(" + transport.responseText + ")");
        
        CheckUpdateSeed(rslt);
        
        if (rslt.ok) 
        {
          Seed.queue_sacr["city" + city].push(rslt.queue_sacr);
          Seed.units["city" + city] = rslt.units;
          Seed.cityData.city[city].population = rslt.cityData_city.population;
          Seed.cityData.city[city].populationCap = rslt.cityData_city.populationCap;

          if(notify)
          {
            notify("Sacrificed troops");
          }
          logit("Sacrifice: City:" + params.cid + " ,Type: " + params.type + " ,Count: " + params.quant);
          logit("Sacrifice: - " + JSON2.stringify(Seed.queue_sacr,null,2));
        }
        else
        {
          if(notify)
          {
            notify("Error - cannot sacrifice (" + rslt.msg + ")");
          }
          logit("Sacrifice: failure - " + JSON2.stringify(rslt, null, 2));
        }
      },
      
      onFailure: function()
      {
        profiler.stop();
        logit("Sacrifice: Failure");
        if(notify)
        {
          notify("Error sacrificing - comms error");
        }
      },
    }, false);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doCancelSacrifice: function (sacrifice, notify)
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    // cancelSacrificing.php
    // &cid=15724&type=6&quant=5000&start=1359672494&eta=1359672910

    params.cid = sacrifice.cityId;
    params.type = sacrifice.unitType;
    params.quant = sacrifice.quantity;
    params.start = sacrifice.start;
    params.eta = sacrifice.eta;

    var profiler = new CM.Profiler("ResponseTime", "train.php");
    new InstantAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/cancelSacrificing.php" + unsafeWindow.g_ajaxsuffix,
    {
      method: "post",
      parameters: params,
      loading: true,

      onSuccess: function(transport)
      {
        profiler.stop();
        var rslt = eval("(" + transport.responseText + ")");

        CheckUpdateSeed(rslt);

        if (rslt.ok)
        {
          // we need to stop the current sacrifice in the queue now
          jQuery.each(Seed.queue_sacr["city" + sacrifice.cityId], function(i)
          {
            queueItem = Seed.queue_sacr["city" + sacrifice.cityId][i];
            if(queueItem.cityId == sacrifice.cityId && queueItem.unitType == sacrifice.unitType)
            {
              logit("Sacrifice: found troops in queue and cancelled");
              Seed.queue_sacr["city" + sacrifice.cityId].splice(i,1);
            }
          });

          if(notify)
          {
            notify("Sacrifice cancelled");
          }

          logit("Sacrifice: Cancel - City:" + params.cid + " ,Type: " + params.type );
        }
        else
        {
          if(notify)
          {
            notify("Error cancelling sacrifice (" + rslt.msg + ")");
          }
          logit("Sacrifice: Cancel Failure - " + JSON2.stringify(rslt, null, 2));
        }
      },

      onFailure: function()
      {
        profiler.stop();
        logit("Sacrifice: Cancel Failure");
        if(notify)
        {
          notify("Error cancelling sacrifice - comms error");
        }
      },
    }, false);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  myThroneStats: function (activeSlot) 
  {
    var t = Tabs.tower;
    var activeSlotItems = Seed.throne.slotEquip[activeSlot];
    var items = {};
    var stats;
   
    var slotNumber;
    
    for(slotNumber in activeSlotItems)
    {
      if(activeSlotItems.hasOwnProperty(slotNumber)) 
      {
        var item = unsafeWindow.kocThroneItems[activeSlotItems[slotNumber]];
        
        items[activeSlotItems[slotNumber]] = item;
      }
    }

    stats = getThroneStats(items); 

    rangeStats = getRangeStats(stats);

    rangeStats.fletch = Seed.tech.tch13;
    
    return rangeStats;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  recordPlayerThrone: function(aid, items) 
  {
    var t = Tabs.tower;
    var stats = {};
    var now = unixTime();

    if(!Options.attackersRange[aid]) 
    {
      Options.attackersRange[aid] = {};
    }

    if(!SessionOptions.attackersRange[aid]) 
    {
      SessionOptions.attackersRange[aid] = {};
      SessionOptions.attackersRange[aid].updated = now;
    }

    stats = getThroneStats(items);
    
    rangeStats = getRangeStats(stats);
    
    updatePlayerRange(aid, rangeStats);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doThronePreset : function (preset)
  {
    var t = Tabs.tower;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
    params.action = 'setPreset';
    params.presetId = preset;
    
    if(!t.throneChangePosted) 
    {
      t.throneChangePosted = true;

      new InstantAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
        
        onSuccess: function (transport) 
        {
          var rslt = eval("(" + transport.responseText + ")");
          
          if(rslt.ok)
          {
            button = '<li id="throneInventoryPreset' + preset + '" class="active">' + preset + '</li>';
            CM.ThroneView.clickActivePreset(button);
            setPresetWidget(preset);
            Seed.throne.activeSlot = preset;
          } 
          
          t.throneChangePosted = false;
        },
        
        onFailure: function () 
        {
          t.throneChangePosted = false;
        },
      });
    }   
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sendalert : function (m)
  {
    var t = Tabs.tower;
    var now = unixTime();
  
    if (Options.celltext.atext)
    {
      t.postToCell (m);
    }
    
    if (Options.alertSound.enabled)
    {
      t.soundTheAlert(m);
      if (m.arrivalTime > Options.alertSound.expireTime)
      {
        Options.alertSound.expireTime = m.arrivalTime;
      }
    }
    
    if (Options.alertConfig.raid)
    {
      Tabs.Raid.StopCityRaids(m.toCityId);
      Options.alertConfig.raidautoswitch[m.toCityId] = true;
    }  
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  ajaxSetDefMode : function (cityId, state, notify)
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid = cityId;
    params.state = state;
    logit("City - " + cityId + ", State - " + state);

    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/gate.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      instant: true,
      
      onSuccess: function (rslt) 
      {
        if (rslt.ok) 
        {
          CheckUpdateSeed(rslt);
          Seed.citystats["city" + cityId].gate = state;

          if(notify) 
          {
            notify (state);
          }
        }
      },

      onFailure: function () 
      {
      }
    })
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  onUnload : function ()
  {
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  postToCell : function (m)
  {
    var t = Tabs.tower;
    var data = {};
    if (m.marchType == null)
    {    // bogus march (returning scouts)
      return;
    }
    
    if (m.marchType == 3)
    {
      if (!Options.alertConfig.scouting)
      {
        return;
      }
      
      data.atkType = 'scout';
    } 
    else if (m.marchType == 4)
    {
      data.atkType = 'atk';
    } 
    else 
    {
      return;
    }

    var city = Cities.byID[m.toCityId];

    if ( city.tileId == m.toTileId )
    {
      data.target = 'city ('+ city.x +','+ city.y+')';
    }
    else 
    {
      if (!Options.alertConfig.wilds)
      {
        return;
      }
      
      data.target = 'wild';
      
      for (k in Seed.wilderness['city'+m.toCityId])
      {
        if (Seed.wilderness['city'+m.toCityId][k].tileId == m.toTileId)
        {
          data.target += Seed.wilderness['city'+m.toCityId][k].xCoord +','+ Seed.wilderness['city'+m.toCityId][k].yCoord;
          break;
        }
      }
    }

    if (Seed.players['u'+m.pid]) 
    {
      data.who = Seed.players['u'+m.pid].n;
    }
    else if (m.players && m.players['u'+m.pid])
    {
      data.who = m.players['u'+m.pid].n;
    }
    else
    {
      data.who = 'Unknown';
    }
  
    if (m.fromXCoord)
    {
      data.who += m.fromXCoord +','+ m.fromYCoord;
    }
    
    data.arrival = unsafeWindow.timestr(parseInt(m.arrivalTime - unixTime()));
    var totTroops = 0;
    data.totTroops = ' '

    for (k in m.unts)
    {
      var uid = parseInt(k.substr (1));
      
      data.totTroops += m.unts[k] +' '+ unsafeWindow.unitcost['unt'+uid][0] +', ';
      totTroops += m.unts[k];
    }

    if (totTroops < Options.alertConfig.minTroops)
    {
      return;
    }

    if ( city.tileId == m.toTileId )
    {
      var emb = getCityBuilding(m.toCityId, CM.BUILDING_TYPES.EMBASSY);
      if (emb.count > 0)
      {
        var availSlots = emb.maxLevel;
        for (k in Seed.queue_atkinc)
        {
          if (Seed.queue_atkinc[k].marchType==2 && Seed.queue_atkinc[k].toCityId==m.toCityId && Cities.byID[Seed.queue_atkinc[k].fromCityId]==null)
          {
            --availSlots;
          }
        }
        
        data.embassy = 'EMB '+ availSlots +'of'+ emb.maxLevel;

        if (t.defMode[m.toCityId] == 0 && Options.alertConfig.defend==true)
        {
            data.stat = 'HIDING';
        }

        if (t.defMode[m.toCityId] == 1 && Options.alertConfig.defend==true)
        {
            data.stat = 'DEFENDING';
        }
      }
    }
    
    data.provider = Options.celltext.provider;
    data.num1 = Options.celltext.num1;
    data.num2 = Options.celltext.num2;
    data.num3 = Options.celltext.num3;
    data.serverId = getServerId();
    data.player = Seed.player['name'];
    data.city = city.name;

    GM_xmlhttpRequest(
    {
      method: 'POST',
      url: 'http://hs151.digitalweb.net/index.php',
      headers: 
      {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
      },
      data: implodeUrlArgs(data),

    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getAttacker: function(march)
  {
    var who = "";
    
    if (Seed.players['u'+march.pid]) 
    {
      who = Seed.players['u'+march.pid].n;
    }
    else if (march.players && march.players['u'+march.pid])
    {
      who = march.players['u'+march.pid].n;
    }
    else
    {
      who = translate('Unknown');
    }
    
    return who;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  postToChat : function (m)
  {
    var t = Tabs.tower;

    if (m.marchType == null)      // bogus march (returning scouts)
    {
      return;
    }

    var city = Cities.byID[m.toCityId];
 
    var target, atkType, who;
    
    if (m.marchType == 3)
    {
      if (!Options.alertConfig.scouting)
      {
        return;
      }
      
      atkType = translate('scouted');
    } 
    else if (m.marchType == 4)
    {
      atkType = translate("attacked");
    } 
    else 
    {
      return;
    }
    
    if ( city.tileId == m.toTileId )
    {
      target = ' | city at ('+ city.x + ',' + city.y + ')';
    }
    else 
    {
      if (!Options.alertConfig.wilds)
      {
        return;
      }
      
      target = translate(' | wilderness');
      
      for (k in Seed.wilderness['city'+m.toCityId])
      {
        if (Seed.wilderness['city'+m.toCityId][k].tileId == m.toTileId)
        {
          target += ' at (' + Seed.wilderness['city' + m.toCityId][k].xCoord + ',' + Seed.wilderness['city' + m.toCityId][k].yCoord + ')';
          break;
        }
      }
    }
    
    who = t.getAttacker(m);
    
    if (m.fromXCoord)
    {
      who += ' at ('+ m.fromXCoord +','+ m.fromYCoord + ')';
    }
    who += ' (' + getDiplomacy(m.aid) + ')';
    
    if(enableCheck(m.aid)) 
    {
      return;
    }
  
    var msg = Options.alertConfig.aPrefix + ' ';

    if(m.marchStatus == 9)
    {
      msg += '..:.The '+ atkType +' on my '+ target +' by '+ who +' has been recalled.';
    }
    else
    {
      msg += '..:.My '+ target +' is being '+ atkType  +' || by '+ who +' || Incoming Troops (arriving in '+ unsafeWindow.timestr(parseInt(m.arrivalTime - unixTime())) +') : ';
    }
    
    var totTroops = 0;

    for (k in m.unts)
    {
      var uid = parseInt(k.substr (1));
      msg += ' | ' + m.unts[k] + ' ' + unsafeWindow.unitcost['unt'+uid][0];
      totTroops += m.unts[k];
    }

    if (totTroops < Options.alertConfig.minTroops)
    {
      return;
    }

    msg = msg.slice (0, -2);
    msg += '.';

    if ( city.tileId == m.toTileId )
    {
      var emb = getCityBuilding(m.toCityId, CM.BUILDING_TYPES.EMBASSY);
      if (emb.count == 0)
      {
        msg += translate(" || My embassy has not been constructed in this kingdom.  Do not attempt to reinforce.");
      }
      else 
      {
        var availSlots = emb.maxLevel;

        for (k in Seed.queue_atkinc)
        {
          if (Seed.queue_atkinc[k].marchType==2 && Seed.queue_atkinc[k].toCityId==m.toCityId && Cities.byID[Seed.queue_atkinc[k].fromCityId]==null)
          {
            --availSlots;
          }
        }
        
        msg += ' || My embassy has '+ availSlots +' of '+ emb.maxLevel +' slots available.';

        if (t.defMode[m.toCityId] == 0 && Options.alertConfig.defend==true)
        {
            msg+= ' || My troops are HIDING!';
        }

        if (t.defMode[m.toCityId] == 1 && Options.alertConfig.defend==true)
        {
            msg+= ' || My troops are DEFENDING!';
        }

        // TODO : for now this is off as tech levels play less part in battles
        if(0)
        {
          msg+= ' || My technology levels are: ';
            + ' | Fl Lv' + parseInt(Seed.tech.tch13)
            + ' | HP Lv'+ parseInt(Seed.tech.tch15)
            + ' | PE Lv'+ parseInt(Seed.tech.tch8)
            + ' | MA Lv'+ parseInt(Seed.tech.tch9)
            + ' | MM Lv'+ parseInt(Seed.tech.tch11)
            + ' | AH Lv'+ parseInt(Seed.tech.tch12);
        }

        var activeSlot = Seed.throne.activeSlot;
        var activeSlotItems = Seed.throne.slotEquip[activeSlot];

        var items = {};
        var stats = {};
        
        var slotNumber;
        
        for(slotNumber in activeSlotItems)
        {
          if(activeSlotItems.hasOwnProperty(slotNumber)) 
          {
            var item = unsafeWindow.kocThroneItems[activeSlotItems[slotNumber]];
            
            items[activeSlotItems[slotNumber]] = item;
          }
        }
        
        stats = getThroneStats(items);

        msg += " || Throne stats active";

        var itemId;
        for (itemId in stats) 
        {
          if (stats.hasOwnProperty(itemId)) 
          {
            var str1 = stats[itemId].name.toString();
            var str2 = stats[itemId].type.toString();

            if (str2.search(/defense|range|attack/i) >= 0) 
            {
              msg += ' | ' + stats[itemId].name + "(" + stats[itemId].type + "): " + stats[itemId].percent;
            }
          }
        }
      }
    }

    t.sendalert(m);

    if (!Options.alertConfig.aChat) 
    {
      return;
    }

    if (ENABLE_TEST_TAB) 
    {
      Tabs.Test.addDiv (msg);
    }

    if (SEND_ALERT_AS_WHISPER)
    {
      sendChat ("/"+ Seed.player.name +' '+ msg);    // Whisper to myself
    }
    else
    {
      sendChat ("/a "+  msg);                        // Alliance chat
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  handleTowerData: function(m)
  {
    var t = Tabs.tower;
    var now = unixTime();
    var target, atkType, who, attackermight, allianceId, allianceName, diplomacy;
    var city = Cities.byID[m.toCityId];
    
    if (DEBUG_TRACE)
      logit("checkTower(): INCOMING at " + unixTime() + ": \n" + inspect(m, 8, 1));
    
    //ATKTYPE
    if (m.marchType == 3) 
    {
      atkType = 'scouted';
      t['scoutCount_' + m.toCityId]++;
    }
    else
    {
      if (m.marchType == 4) 
      {
        atkType = 'attacked';
        t['attackCount_' + m.toCityId]++;
      }
      else 
      {
        return;
      }
    }
    
    //TARGET
    if (city.tileId == m.toTileId)
    {
      target = 'City at ' + city.x + ',' + city.y;
    }
    else 
    {
      target = 'Wilderness';

      for (k in Seed.wilderness['city' + m.toCityId]) 
      {
        if (Seed.wilderness['city' + m.toCityId][k].tileId == m.toTileId) 
        {
          target += ' at ' + Seed.wilderness['city' + m.toCityId][k].xCoord + ',' + Seed.wilderness['city' + m.toCityId][k].yCoord;
          break;
        }
      }
    }

    //CITYNAME
    var cityName = Cities.byID[m.toCityId].name;
    
    //TROOPS
    var units = [];
    for (i = 0; i < 13; i++)
    {
        units[i] = 0;
    }
    
    for (k in m.unts) 
    {
      var uid = parseInt(k.substr(1));
      
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Supply Troop')
        units[1] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Militiaman')
        units[2] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Scout')
        units[3] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Pikeman')
        units[4] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Swordsman')
        units[5] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Archer')
        units[6] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Cavalry')
        units[7] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Heavy Cavalry')
        units[8] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Supply Wagon')
        units[9] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Ballista')
        units[10] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Battering Ram')
        units[11] = m.unts[k];
      if (unsafeWindow.unitcost['unt' + uid][0] == 'Catapult')
        units[12] = m.unts[k];
    }
    
    //ATTACKERS INFORMATION
    if (Seed.players['u' + m.pid]) 
    {
      who = Seed.players['u' + m.pid].n;
      attackermight = Seed.players['u' + m.pid].m;
      allianceId = Seed.players['u' + m.pid].a;
      allianceName = Seed.allianceNames[allianceId];
      diplomacy = getDiplomacy(allianceId);
    }
    else
    {
      if (m.players && m.players['u' + m.pid]) 
      {
        who = m.players['u' + m.pid].n;
        attackermight = parseInt(m.players['u' + m.pid].m);
        allianceId = 'a' + m.players['u' + m.pid].a;
        allianceName = Seed.allianceNames[allianceId];
        diplomacy = getDiplomacy(allianceId);
      }
      else 
      {
        who = 'n.A.';
        attackermight = 'n.A.';
        allianceId = 'n.A.';
        allianceName = 'n.A.';
        diplomacy = 'n.A.';
      }
    }
    
    //SOURCE
    if (m.fromXCoord)
    {
      var source = m.fromXCoord + ',' + m.fromYCoord;
    }
    else
    {
      var source = 'n.A.';
    }
    
    var arrivingDatetime = new Date();
    arrivingDatetime.setTime(m.arrivalTime * 1000);
    var count = t.towerMarches.length + 1;
    
    t.towerMarches[count] = 
    {
      added: now,
      cityId: m.toCityId,
      target: target,
      arrival: parseIntNan(m.arrivalTime),
      atkType: atkType,
      who: who,
      attackermight: attackermight,
      allianceName: allianceName,
      diplomacy: diplomacy,
      rtime: unsafeWindow.timestr(parseInt(m.arrivalTime - unixTime())),
      arrivingDatetime: arrivingDatetime,
      source:source,
      units: units,
    };
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  showTowerIncoming: function(cityId){
    var t = Tabs.tower;
    var popTowerIncoming = null;
    var cityName = Tabs.build.getCityNameById(cityId);
        
    if (t.popTowerIncoming == null) {
        t.popTowerIncoming = new pbPopup('pbtower_' + cityId, 0, 0, 820, 500, true, function() {clearTimeout (t.timer);});
    }
    t.popTowerIncoming.show(false);
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbTabPad" id="pbCityTowerContent">';
    t.popTowerIncoming.getMainDiv().innerHTML = '</table></div>' + m;
    t.popTowerIncoming.getTopDiv().innerHTML = '<TD width="200px"><B>'+translate("Tower Report of")+' ' + cityName + '</b></td></td>';
    t.addCityData2Pop(cityId);
    t.popTowerIncoming.show(true);
    clearTimeout (t.timer);
    t.timer = setTimeout (function() {t.showTowerIncoming(cityId)}, 5000);        
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addCityData2Pop: function(cityId)
  {
    var t = Tabs.tower;
    var rownum = 0;
    var names = ['Supply', 'Mil', 'Scout', 'Pike', 'Sword', 'Archer', 'Cav', 'Heavy', 'Wagon', 'Balli', 'Ram', 'Cat'];
    enc = {};
    numSlots = 0;
    var row = document.getElementById('pbCityTowerContent').innerHTML = "";
    if (matTypeof(Seed.queue_atkinc) != 'array') 
    {
      for (k in Seed.queue_atkinc) 
      {
        march = Seed.queue_atkinc[k];
        if (march.marchType == 2) 
        {
          ++numSlots;
          city = march.toCityId;
          from = march.fromPlayerId;
          
          if (!enc[city])
            enc[city] = {};
          
          if (!enc[city][from])
            enc[city][from] = [];
          
          k = [];
          k[0] = parseInt(march.knightCombat);
          
          for (i = 1; i < 13; i++) 
          {
            if (Options.encRemaining)
              k[i] = parseInt(march['unit' + i + 'Return']);
            else
              k[i] = parseInt(march['unit' + i + 'Count']);
          }
          k[14] = parseInt(march.marchStatus);
          var now = unixTime();
          k[15] = parseInt(march.destinationUnixTime) - now;
          enc[city][from].push(k);
        }
      }
    }
    var s1 = '';
    var s2 = '';
    var s3 = '';
    var tot = [];
    var atk = [];
    for (i = 0; i < 13; i++) {
      tot[i] = 0;
      atk[i] = 0;
    }

    s1 += '<STYLE> .tot{background:#f0e0f8;} .city{background:#ffffaa;} .attack{background:#FF9999;} .own{background:#66FF66;}</style>';
    s1 += '<TABLE cellspacing=0 width=100%><TR align=right><TD align=center width=16%></td>';
    
    for (k = 0; k < names.length; k++)
        s1 += '<TD width=7%><B>' + names[k] + '</b></td>';
    s1 += '</tr>';
    dest = cityId;
    if (enc[dest]) {
      for (p in enc[dest]) {
        try {
            player = Seed.players['u' + p].n;
        }
        catch (err) {
            player = '???';
        }
        for (m = 0; m < enc[dest][p].length; m++) {
          status = '';
          if (enc[dest][p][m][14] == 1) {
            status = ' (' + timestr(enc[dest][p][m][15]) + ')'; 
            if (enc[dest][p][m][15] < 0)
              status = ' (enc)';  
            else
               status = ' (' + timestr(enc[dest][p][m][15]) + ')';  
          }
          
          if (enc[dest][p][m][14] == 2) {
            status = ' (enc)';  
          }

          s1 += '<TR align=right><TD align=left class="city">' + player + status +'</td>'
          for (i = 1; i < 13; i++) {
              num = enc[dest][p][m][i];
              s1 += '<TD class="city">' + num + '</td>';
              tot[i] += num;
          }
          //s1 += '<TD><INPUT id=sendhome_' + numSlots + ' type=submit value="Home" style="border:1px solid black; background-color:red;"></td></tr>';
        }
      }
    } else {
      s1 += '<TR align=right><TD align=left class="city"><B>'+translate("Reinforcment")+':</b></td>'
      for (i = 1; i < 13; i++) {
          s1 += '<TD class="city">0</td>';
      }
    }
    s1 += '<TR align=right><TD colspan=14><BR></tr>';
    s1 += '<TR align=right><TD class="own" align=left><B>'+translate("Own Troops")+':</b></td>';
    //OWNTROOPS
    var ownTroops = "";
    for (r = 1; r < 13; r++) {
        cityString = 'city' + cityId;
        num = parseInt(Seed.units[cityString]['unt' + r]);
        s1 += '<TD class="own">' + num + '</td>';
        tot[r] += num;
    }
    s1 += '<TD class="city"></td><TR><TD colspan=14><BR></td></tr><TR align=right><TD class="tot" align=left><B>'+translate("Defenders")+':</b></td>';
    for (i = 1; i < 13; i++)
        s1 += '<TD class="tot">' + tot[i] + '</td>';      
    s3 += '</tr></table>';
        
    s3 += '<TD class="city"></td><TR><TD colspan=14><BR></td></tr><TR align=right><TD class="tot" align=left><B>'+translate("Incoming Attacks")+':</b></td>';
        
    var names = ['Supply', 'Mil', 'Scout', 'Pike', 'Sword', 'Archer', 'Cav', 'Heavy', 'Wagon', 'Balli', 'Ram', 'Cat'];
    if (t.towerMarches.length > 0) {
      for (k in t.towerMarches) {
        if (typeof t.towerMarches[k].atkType != 'undefined') {
          if (t.towerMarches[k].cityId == cityId) {
            s3 += '<TABLE cellspacing=0 width=100%><TR>';
            
            if (t.towerMarches[k].atkType == 'attacked') {
                s3 += '<TD rowspan=2 width=5%><B><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_30.jpg?6545"></b></td>';
            }
            else
                if (t.towerMarches[k].atkType == 'scouted') {
                    s3 += '<TD rowspan=2 width=5%><B><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_30.jpg?6545"></b></td>';
                }
            s3 += '<TD width=15%><B>'+translate("Location")+'</b></td>';
            s3 += '<TD width=15%><B>'+translate("Name")+'</b></td>';
            s3 += '<TD width=10%><B>'+translate("Source")+': </b></td><TD width=10%>' + t.towerMarches[k].source + '</td>';
            s3 += '<TD width=10%><B>'+translate("Might")+': </b></td><TD width=10%>' + t.towerMarches[k].attackermight + '</td>';
            s3 += '<TD width=10%><B>'+translate("Alliance")+': </b></td><TD width=10%>' + t.towerMarches[k].allianceName + '</td>';
            s3 += '<TD width=10%><B>'+translate("State")+': </b></td><TD width=10%>' + t.towerMarches[k].diplomacy + '</td></tr>';
            s3 += '<TR><TD width=10%  >' + t.towerMarches[k].target + '</td>';
            s3 += '<TD  >' + t.towerMarches[k].who + '</td>';
            s3 += '<TD><B>'+translate("Remaining")+': </b></td><TD width=10%>' + t.towerMarches[k].rtime + '</td>';
            s3 += '<TD><B>'+translate("Arrival")+': </b></td><TD  colspan=5 width=10%>' + t.towerMarches[k].arrivingDatetime + '</td></tr>';
            s3 += '</tr></table>';
            s3 += '<TABLE cellspacing=0 width=100%><TR align=right><TD align=left width=16%></td>';
            for (n = 0; n < names.length; n++)
                s3 += '<TD width=7%><B>' + names[n] + '</b></td>';
            s3 += '</tr><TR align=right><TD class="attack" align=left><B>Units:</td>';
            for (u = 1; u < 13; u++) {
                num = t.towerMarches[k].units[u];
                s3 += '<TD class="attack">' + num + '</td>';
                atk[u] += parseInt(num);
            }
            s3 += '</tr></table>';
          }
        }
      }
    }
    s2 += '<TR><TD colspan=14><BR></td></tr><TR align=right><TD class="attack" align=left><B>'+translate("Attackers")+':</b></td>';
    
    for (a = 1; a < 13; a++)
    {
      s2 += '<TD class="attack" width=7%>' + atk[a] + '</td>';
    }
    
    var html = s1 + s2 + s3;
    document.getElementById('pbCityTowerContent').innerHTML = html;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sendReinforcementsHome : function (marchId, notify)
  {
    var march = Seed.queue_atkinc['m'+ marchId];

    if (march == null)
    {
      return;
    }    
    
    var params = uW.Object.clone(uW.g_ajaxparams);
    params.mid = marchId;
    params.cid = march.toCityId;
    params.fromUid = march.fromPlayerId;
    params.fromCid = march.fromCityId;
   
    new InstantAjaxRequest(uW.g_ajaxpath + "ajax/kickoutReinforcements.php" + uW.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (rslt) 
      {
        if (rslt.ok)
        {
          var upkeep = 0;
          
          for (var i=1; i<13; i++)
          {
            upkeep += parseInt(march["unit" + i + "Return"]) * parseInt(uW.unitupkeeps[i]);
          }
          
          uW.seed.resources["city"+ march.toCityId].rec1[3] -= upkeep;
          
          if (parseInt(march.fromPlayerId) == parseInt(uW.tvuid)) 
          {
            var mymarch = uW.seed.queue_atkp["city" + march.fromCityId]["m" + marchId];
            var marchtime = Math.abs(parseInt(mymarch.destinationUnixTime) - parseInt(mymarch.eventUnixTime));
            mymarch.returnUnixTime = unixTime() + marchtime;
            mymarch.marchStatus = 8;
          }
          
          delete uW.seed.queue_atkinc["m" + marchId];
          
          if (notify != null)
          {
            notify(null);
          }
        } 
        else 
        {
          if (notify != null)
          {
            notify(rslt.errorMsg);
          }
        }
      },
      
      onFailure: function () 
      {
        if (notify != null)
        {
          notify(rslt.errorMsg);
        }
      },
    });
  },
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: build
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.build = 
{
  tabOrder: 20,
  tabLabel: 'Build',
  myDiv: null,
  timer: null,
  buildTab: null,
  koc_buildslot: null,
  currentBuildMode: null,
  buildStates: [],
  loaded_bQ: [],
  lbQ: [],
  cityBusy: {},
  toolsMode: null,
  buildingSelect:'all',

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init: function(div)
  {
    var t = Tabs.build;
    t.myDiv = div;
    t.koc_buildslot = unsafeWindow.buildslot; //save original koc function
    t.currentBuildMode = "build";

    t.buildStates = 
    {
      running: false,
      help: false,
    };
    t.readBuildStates();
      
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      t["bQ_" + Cities.cities[i].id] = JSON2.parse(GM_getValue('bQ_' + getServerId() + '_' + Cities.cities[i].id, '[]'));
      
      if (typeof t["bQ_" + Cities.cities[i].id] == 'undefined' || (t["bQ_" + Cities.cities[i].id]) == "") {
        t["bQ_" + Cities.cities[i].id] = [];
      }
    }
      
    var m = '<DIV id=pbBuildDivF class=pbStat>'+translate("BUILD FUNCTIONS")+'</div><TABLE id=pbbuildfunctions width=100% height=0% class=pbTab><TR>';
    
    if (t.buildStates.running == false) {
      m += '<TD><INPUT id=pbBuildRunning type=submit value="'+translate("Auto Build = OFF")+'"></td>';
    }
    else {
      m += '<TD><INPUT id=pbBuildRunning type=submit value="'+translate("Auto Build = ON")+'"></td>';
    }
    
    m += '<TD><INPUT id=pbBuildMode type=submit value="'+translate("Build Mode = OFF")+'"></td>';
    m += '<TD>'+translate("Build Type")+': <SELECT id="pbBuildType">\
      <OPTION value=build>'+translate("level up")+'</option>\
      <OPTION value=max>'+translate("level max")+'</option>\
      <OPTION value=destruct>'+translate("destruct")+'</option>\
      </select></td>';
    m += '<TD><INPUT id=pbHelpRequest type=checkbox '+ (t.buildStates.help?' CHECKED':'') +'\></td><TD>'+translate("Ask for help")+'?</td>';
    m += '</tr></table></div>';
    m += '<DIV id=pbBuildDivQ class=pbStat>'+translate("BUILD QUEUES")+'</div><TABLE id=pbbuildqueues width=100% height=0% class=pbentry><TR>';
    
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      m += '<TD colspan=2><CENTER><B>' + Cities.cities[i].name + '</b></center></td>';
    }
    m += '</tr><TR>';
    
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      m += '<TD colspan=2><CENTER><INPUT id=pbbuild_' + Cities.cities[i].id + ' type=submit value="'+translate("Show")+'"></center></td>';
    }
    m += '</tr><TR>';
    
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      m += '<TD colspan=2><CENTER><INPUT id=pbCancelAll_' + Cities.cities[i].id + ' type=submit value="'+translate("Cancel All")+'"></center></td>';
    }
    m += '</tr><TR>';
      
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      m += '<TD>Qc:</td><TD id=pbbuildcount_' + Cities.cities[i].id + '>' + t["bQ_" + Cities.cities[i].id].length + '</td>';
    }
    m += '</tr><TR>';
    
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      t['totalTime_' + Cities.cities[i].id] = 0;
      cbQ = t["bQ_" + Cities.cities[i].id];
      
      if (typeof cbQ != 'undefined') 
      {
        for (var j = 0; j < cbQ.length; j++) 
        {
          t['totalTime_' + Cities.cities[i].id] = parseInt(t['totalTime_' + Cities.cities[i].id]) + parseInt(cbQ[j].buildingTime);
        }
        
        timestring = timestr(t['totalTime_' + Cities.cities[i].id]);
      }
      
      m += '<TD>Tt:</td><TD id=pbbuildtotal_' + Cities.cities[i].id + '>' + timestring + '</td>';
    }
    
    m += '</tr></table><SPAN class=boldRed id=pbbuildError></span>';
    t.myDiv.innerHTML = m;
      
    for (var i = 0; i < Cities.cities.length; i++) 
    {
      var cityId = Cities.cities[i].id;
      var btnName = 'pbbuild_' + cityId;
      addQueueEventListener(cityId, btnName);
      var btn2Name = 'pbCancelAll_' + cityId;
      CancelAllEventListener(cityId, btn2Name);
      t.showBuildQueue(cityId, false);
    }

    t.e_autoBuild(); //start checking if we can build someting
      
    document.getElementById('pbBuildType').addEventListener('change', function(){t.setBuildMode(this.value);}, false);
    document.getElementById('pbBuildRunning').addEventListener('click', function()
    {
      t.toggleStateRunning(this);
    }, false);
    document.getElementById('pbBuildMode').addEventListener('click', function()
    {
      t.toggleStateMode(this);
    }, false);
    document.getElementById('pbHelpRequest').addEventListener ('change', function ()
    {
      t.buildStates.help = (document.getElementById('pbHelpRequest').checked);
      t.saveBuildStates();
    }, false);
      
    window.addEventListener('unload', t.onUnload, false);
      
    function addQueueEventListener(cityId, name) 
    {
      document.getElementById(name).addEventListener('click', function()
      {
        t.showBuildQueue(cityId, true);
      }, false);
    }
      
    function CancelAllEventListener(cityId, name)
    {
      document.getElementById(name).addEventListener('click', function()
      {
        t["bQ_" + cityId] = [];
        t['totalTime_' + cityId] = 0;
        document.getElementById('pbbuildcount_' + cityId).innerHTML = 0;
        document.getElementById('pbbuildtotal_' + cityId).innerHTML = timestr(0);
      }, false);
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  setBuildMode: function (type) 
  {
    var t = Tabs.build;
    t.currentBuildMode = type;
  },  
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_autoBuild: function()
  {
    var t = Tabs.build;
    
    var buildInterval = 2 * 1000; // 2 seconds between checks by default

    document.getElementById('pbbuildError').innerHTML = '';

    if (t.buildStates.running == true) 
    {
      var now = unixTime();
      //logit ('Seed.queue_con: (now='+ now +')\n'+ inspect (Seed.queue_con, 3));

      for (var i = 0; i < Cities.cities.length; i++) 
      {
        var cityId = Cities.cities[i].id;
        var isBusy = false;
        var qcon = Seed.queue_con["city" + cityId];
        
        if (matTypeof(qcon)=='array' && qcon.length > 0) 
        {
          if ((parseInt(qcon[0][4]) + 10) > now)
          {
            isBusy = true;
          }
          else
          {
            qcon.shift();   // remove expired build from queue        
            logit("Build: Remove expired item from build queue");
          }
        }              
        
        //logit ('City #'+ (i+1) + ' : busy='+ isBusy);               
        
        if (isBusy) 
        {
          //TODO add info of remaining build time and queue infos
        } 
        else 
        {
          var cityBusy = false;
          
          if(t.cityBusy["city" + cityId])
          {
            cityBusy = true;
          }
          
          if (t["bQ_" + cityId].length > 0 && !cityBusy) 
          { // something to do?
            var bQi = t["bQ_" + cityId][0];   //take first queue item to build
            t.cityBusy["city" + cityId] = true;
            t.doOne(bQi);;
            buildInterval = 10 * 1000; // we tried to build so use longer interval
            //setTimeout(t.e_autoBuild, 10000); //should be at least 10
            //return; // we need to make sure that there is enough time for each ajax request to not overwrite the vaule that are needed by the next run
          }
        }         
      }
    }
    
    setTimeout(t.e_autoBuild, buildInterval); //should be at least 10
  },  
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doOne : function (bQi)
  {
    var t = Tabs.build;
    var currentcityid = parseInt(bQi.cityId);
    var cityName = t.getCityNameById(currentcityid);
    var time = parseInt(bQi.buildingTime);
    var mult = parseInt(bQi.buildingMult);
    var attempt = parseInt(bQi.buildingAttempt);
    
    var mode = bQi.buildingMode;
    
    var citpos = parseInt(bQi.buildingPos);

    var bypasscheck = false;
    
    if ((Seed.buildings['city' + currentcityid]["pos" + citpos] == undefined))
    {
      // This will only be performed if there is not a building in the current location (e.g. startup tab)
      bypasscheck = true;
    }
      
    if(!bypasscheck)
    { 
      var l_bdgid = parseInt(bQi.buildingType); //JUST FOR CHECK
      var bdgid = parseInt(Seed.buildings['city' + currentcityid]["pos" + citpos][0]);
      
      var l_curlvl = parseInt(bQi.buildingLevel); //JUST FOR CHECK
      var curlvl = parseInt(Seed.buildings['city' + currentcityid]["pos" + citpos][1]);

      var l_bid = parseInt(bQi.buildingId); //JUST FOR CHECK
      var bid = parseInt(Seed.buildings["city" + currentcityid]["pos" + citpos][3]);
                  
      if (curlvl > 8 && mode == 'build') 
      {
        t.cancelQueueElement(0, currentcityid, time, false);
        actionLog(cityName + " - " + translate("Queue item deleted: Building Level equals 9 or higher!!!"));
        logit("Build: Queue item deleted: Building Level equals 9 or higher - curlvl > 8 && mode == 'build' :" + curlvl + "," + mode);
        t.cityBusy["city" + currentcityid] = false;
        return;
      };
      
      if (isNaN(curlvl)) 
      {
        t.cancelQueueElement(0, currentcityid, time, false);
        actionLog(cityName + " - " + translate("Found no correct value for current building"));
        logit("Build: Found no correct value for current building - isNaN(curlvl) :" + l_curlvl + "," + curlvl);
        t.cityBusy["city" + currentcityid] = false;
        return;
      }
      
      if (l_bdgid != bdgid) {
        t.cancelQueueElement(0, currentcityid, time, false);
        actionLog(cityName + " - " + translate("Found no correct value for current building!!!!"));
        logit("Build: Found no correct value for current building - l_bdgid != bdgid :" + l_bdgid + "," + bdgid);
        t.cityBusy["city" + currentcityid] = false;
        return;
      }
      
      if (l_bid != bid) 
      {
        t.cancelQueueElement(0, currentcityid, time, false);
        actionLog(cityName + " - " + translate("Building ID does not match - l_bid != bid :" + l_bid + "," + bid ));
        logit("Build: Building ID does not match!!!!");
        t.cityBusy["city" + currentcityid] = false;
        return;
      }
      
      if (l_curlvl < curlvl) 
      {
        t.cancelQueueElement(0, currentcityid, time, false);
        actionLog(cityName + " - " + translate("Queue item deleted: Buildinglevel is equal or higher!!!"));
        logit("Build: Queue item deleted: Buildinglevel is equal or higher!!!");
        t.cityBusy["city" + currentcityid] = false;
        return;
      }
      
      if (l_curlvl > curlvl && mode == 'build' && (l_curlvl > 8 || curlvl > 8)) 
      {
        t.requeueQueueElement(bQi);
        t.cityBusy["city" + currentcityid] = false;
        logit("Build: Queue item deleted: Building Level equals 9 or higher!!!");
        return;
      }
    } 
    else 
    {
      var l_bdgid = parseInt(bQi.buildingType); //JUST FOR CHECK
      var bdgid = l_bdgid;
      
      var l_curlvl = parseInt(bQi.buildingLevel); //JUST FOR CHECK
      var curlvl = l_curlvl;

      var l_bid = parseInt(bQi.buildingId); //JUST FOR CHECK
      var bid = l_bid;
      
      logit("Build: building initial item at position - " + bid);
    }

    if (mode == 'destruct') 
    {
      var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
      params.cid = currentcityid;
      params.bid = "";
      params.pos = citpos;
      params.lv = curlvl - 1;

      if (curlvl >= 1) 
      {
        params.bid = bid;
      }

      params.type = bdgid;
      
      new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/destruct.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        
        onSuccess: function(rslt)
        {
          CheckUpdateSeed(rslt);
            
          if (rslt.ok) 
          {
            actionLog("Destructing " + unsafeWindow.buildingcost['bdg' + bdgid][0] + " at " + cityName);
            Seed.queue_con["city" + currentcityid].push([bdgid, 0, parseInt(rslt.buildingId), unsafeWindow.unixtime(), unsafeWindow.unixtime() + time, 0, time, citpos]);

            if (params.cid == unsafeWindow.currentcityid)
              unsafeWindow.update_bdg();

            if (document.getElementById('pbHelpRequest').checked == true)
              t.bot_gethelp(params.bid, currentcityid);

            t.cancelQueueElement(0, currentcityid, time, false);
          } 
          else 
          {
            var errmsg = unsafeWindow.printLocalError(rslt.error_code || null, rslt.msg || null, rslt.feedback || null);
            t.requeueQueueElement(bQi);
            document.getElementById('pbbuildError').innerHTML = errmsg;
            logit(errmsg);
          }
        },
        
        onFailure: function()
        {
          document.getElementById('pbbuildError').innerHTML = translate("Connection Error while destructing! Please try later again");
        }
      })
    }
    
    if (mode == 'build') 
    {
      var invalid = false;
      var chk = unsafeWindow.checkreq("bdg", bdgid, curlvl); //check if all requirements are met
      
      for (var c = 0; c < chk[3].length; c++) 
      {
        if (chk[3][c] == 0) 
        {
          invalid = true;
        }
      }
      
      if (invalid == false) 
      {             
        var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
        params.cid = currentcityid;
        params.bid = "";
        params.pos = citpos;
        params.lv = curlvl + 1;
        
        if (params.lv > 9)
        { //make sure that no level 10+ is built
          t.cancelQueueElement(0, currentcityid, time, false);
          actionLog(cityName + " - " + translate("Queue item deleted: Tryed to build level 10+ building! Please report if this happens!!!"));
          t.cityBusy["city" + currentcityid] = false;
          return;
        }
        
        if (params.lv > 1) 
        {
          params.bid = bid;
        }
        
        params.type = bdgid;
        
        new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/construct.php" + unsafeWindow.g_ajaxsuffix, 
        {
          method: "post",
          parameters: params,
          
          onSuccess: function(rslt)
          {
            CheckUpdateSeed(rslt);
              
            if (rslt.ok) 
            {
              actionLog(translate("Building")+" " + unsafeWindow.buildingcost['bdg' + bdgid][0] + " Level " + params.lv + " at " + cityName);               
              Seed.resources["city" + currentcityid].rec1[0] -= parseInt(unsafeWindow.buildingcost["bdg" + bdgid][1]) * mult * 3600;
              Seed.resources["city" + currentcityid].rec2[0] -= parseInt(unsafeWindow.buildingcost["bdg" + bdgid][2]) * mult * 3600;
              Seed.resources["city" + currentcityid].rec3[0] -= parseInt(unsafeWindow.buildingcost["bdg" + bdgid][3]) * mult * 3600;
              Seed.resources["city" + currentcityid].rec4[0] -= parseInt(unsafeWindow.buildingcost["bdg" + bdgid][4]) * mult * 3600;
              Seed.citystats["city" + currentcityid].gold[0] -= parseInt(unsafeWindow.buildingcost["bdg" + bdgid][5]) * mult;
              Seed.queue_con["city" + currentcityid].push([bdgid, curlvl + 1, parseInt(rslt.buildingId), unsafeWindow.unixtime(),  unsafeWindow.unixtime() + time, 0, time, citpos]);           
              
              if (curlvl == 0) 
              {
                Seed.buildings["city" + params.cid]["pos" + params.pos] = [bdgid, 0, params.pos, rslt.buildingId];
              }

              //unsafeWindow.Modal.hideModalAll();
              unsafeWindow.queue_changetab_building();
              unsafeWindow.modal_build_show_state();

              if (params.cid == unsafeWindow.currentcityid)
                unsafeWindow.update_bdg();
              
              if (document.getElementById('pbHelpRequest').checked == true)
                t.bot_gethelp(params.bid, currentcityid);
              
              logit("Build: Build submitted - city:" + params.cid + ", pos:" + params.pos + ", lvl:" + params.lv);
              
              t.cancelQueueElement(0, currentcityid, time, false);
            } 
            else 
            {
              var errmsg = unsafeWindow.printLocalError(rslt.error_code || null, rslt.msg || null, rslt.feedback || null);
              
              if (rslt.error_code == 103) 
              { // building has already the target level => just  delete
                t.cancelQueueElement(0, currentcityid, time, false);
                actionLog(cityName + " - " + translate("Queue item deleted: Building at this Level already exists or build process already started!"));
                logit("Build: Error - Queue item deleted: Building at this Level already exists or build process already started!");
              } 
              else 
              {
                t.requeueQueueElement(bQi);
                jQuery('pbbuildError').html(Cities.byID[currentcityid].name +': '+ errmsg + translate(" Item was requeued. Check for retry count."));
                logit("Build: Error - Item was requeued");
              }
              
              logit("Build: Error - msg:" + errmsg);
              logit("Build: Error - rslt:" + JSON2.stringify(rslt,null,2));
            }
          },
          
          onFailure: function()
          {
            document.getElementById('pbbuildError').innerHTML = translate("Connection Error while building! Please try later again");
          }
        });
      } 
      else 
      {
        t.requeueQueueElement(bQi); // requeue item if check is invalid
        logit("Build: item failed build checks, requeue");
      }
    }

    t.cityBusy["city" + currentcityid] = false;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  requeueQueueElement: function (bQi) 
  {
    var t = Tabs.build;
    var cityId = bQi.cityId;
    var buildingPos = parseInt(bQi.buildingPos);
    var buildingId = parseInt(bQi.buildingId);
    var buildingLevel = parseInt(bQi.buildingLevel);
    var buildingType = parseInt(bQi.buildingType);
    var buildingTime = parseInt(bQi.buildingTime);
    var buildingMult = parseInt(bQi.buildingMult);
    var buildingAttempts = parseInt(bQi.buildingAttempts);
    var buildingMode = bQi.buildingMode;
    
    t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts + 1, buildingMult, buildingMode); // requeue item
    t.cancelQueueElement(0, cityId, buildingTime, false); // delete Queue Item
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show: function(){
    var t = Tabs.build;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  bot_buildslot: function(c, a)
  {
    var t = Tabs.build;
    var cityId = t.getCurrentCityId();
    var buildingPos   = c.id.split("_")[1];
    var buildingType  = parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][0]);
    var buildingLevel = parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
    var buildingId    = parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][3]);
    
    //logit("Build: build request - c: " + JSON2.stringify(c, null, 2));
    //logit("Build: build request - a: " + JSON2.stringify(a, null, 2));
    
    logit("Build: Pos: " + buildingPos + " Type: " + buildingType + " Level: " + buildingLevel + " Id: " + buildingId);
      var buildingAttempts = 0;
    
    var loaded_bQ = t["bQ_" + cityId];
    
    if (typeof Seed.queue_con['city' + cityId][0] != 'undefined') 
    {
      var current_construction_pos = Seed.queue_con['city' + cityId][0][2];
    } 
    else 
    {
      var current_construction_pos = "";
    }
    
    if (loaded_bQ.length == 0 && current_construction_pos != "" ) 
    { //check anyway if there is currently build in progess for this specific building
      if (current_construction_pos != 'NaN' && current_construction_pos == buildingId) 
      {
        buildingLevel += 1;
      }
    } 
    else 
    {
      if (current_construction_pos != "" && current_construction_pos == buildingId) 
      {
        buildingLevel += 1;
      }

      for (var i = 0; i < loaded_bQ.length; i++) 
      { 
        // check if there are already queue items for this building or the building is currently building
        var loadedCity = loaded_bQ[i].cityId;
        var loadedSlot = loaded_bQ[i].buildingPos;

        // TODO we may be adding this twice
        logit("Build: build level requested = " + buildingLevel);
        if (loadedSlot == buildingPos && loadedCity == cityId) 
        {
          logit("Build: item is in build queue so increase the level we want to build now");
          buildingLevel += 1;
        }

        if (loaded_bQ[i].buildingMode == 'destruct' && loadedSlot == buildingPos && loadedCity == cityId) 
        { 
          // for now dont show the message as it just gets in the way
          if(false)
          {
            // check if destruction is already in queue
            t.modalmessage(translate("Destruction already in Queue!"));
          }
          return;
        }
      }
    }

    if (t.currentBuildMode == "build") 
    {
      if (buildingLevel >= 9) 
      {
        // for now we do not want the message we will just not add it into the queue
        if(false)
        {
          t.modalmessage(translate('Due to building requirements (DI), buildings above level 9\nshould be manualy built.'));
        }
        return;
      }
      
      var buildingMode = "build";
      var result = t.calculateQueueValues(cityId, buildingLevel, buildingType, buildingMode);
      var buildingMult = result[0];
      var buildingTime = result[1];
      var queueId = loaded_bQ.length;
      t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode);
      t._addTab(queueId, cityId, buildingType, buildingTime, buildingLevel, buildingAttempts, buildingMode);
    }

    if (t.currentBuildMode == "max") 
    {
      var buildingMode = "build";
      
      for (var bL = buildingLevel; bL <9; bL++) 
      {
        var queueId = loaded_bQ.length;
        var result = t.calculateQueueValues(cityId, bL, buildingType, buildingMode);
        var buildingMult = result[0];
        var buildingTime = result[1];
        queueId = queueId ;
        t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult, buildingMode);
        t._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
      }
    }
    
    if (t.currentBuildMode == "destruct") 
    {
      var buildingMode = "destruct";
      var result = t.calculateQueueValues(cityId, buildingLevel, buildingType, buildingMode);
      var buildingMult = result[0];
      var buildingTime = result[1];
      var queueId = loaded_bQ.length;
      t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode);
      t._addTab(queueId, cityId, buildingType, buildingTime, buildingLevel, buildingAttempts, buildingMode);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  calculateQueueValues: function (cityId, buildingLevel, buildingType, buildingMode) 
  {
    var t = Tabs.build;
    var now = unixTime();
    
    if (buildingMode == 'build') 
    {
      var buildingMult = Math.pow(2, buildingLevel);
    } 

    if (buildingMode == 'destruct') 
    {
      var buildingMult = Math.pow(2, buildingLevel - 2);
    }
        
    var knights = Seed.knights["city" + cityId];

    if (knights) 
    {
      var polKniId = parseInt(Seed.leaders['city' + cityId].politicsKnightId);
      
      if (polKniId) 
      {
        var polValue = parseInt(Seed.knights['city' + cityId]['knt' + polKniId].politics);
        var polBoost = parseInt(Seed.knights['city' + cityId]['knt' + polKniId].politicsBoostExpireUnixtime);
        
        if ((polBoost - now) > 0) 
        {
          polValue = parseInt(polValue * 1.25);
        }
      } 
      else 
      {
        polValue = 0;
      }
    } 
    else 
    {
      polValue = 0;
    }
        
    var buildingTime = unsafeWindow.buildingcost["bdg" + buildingType][7] * buildingMult;
    var throneBoost = (+throneEffectBonus(78));

    if (parseInt(buildingType) < 6 && parseInt(buildingType) > 0 && buildingMult == 1) 
    {
        buildingTime = 15;
    }
    
    if (buildingMode == 'build') 
    {
      buildingTime = parseInt(buildingTime / (1 + (0.005 * polValue) + (0.1 * parseInt(Seed.tech.tch16)) + (parseInt(throneBoost) / 100)));
    } 
    
    if (buildingMode == 'destruct') 
    {
      buildingTime = buildingTime / (1 + (0.005 * polValue) + (0.1 * parseInt(Seed.tech.tch16)) + (parseInt(throneBoost) / 100));
      
      if (buildingTime % 1 > 0) 
      {
        buildingTime = parseInt(buildingTime);
      }
    }
    
    var result = new Array(buildingMult, buildingTime);

    return result;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  bot_buildguardian: function(c, a) 
  {
    var t = Tabs.build;
    var cityId = t.getCurrentCityId();
    var buildingType  = 50;
    
    for(i=0; i < Cities.numCities; i++) 
    {
      if(Seed.guardian[i].cityId == cityId) 
      {
        var buildingLevel = Seed.guardian[i].level;
        break;
      }
    }
    
    var buildingId    = parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][3]);

    if (DEBUG_TRACE) logit("Pos: " + buildingPos + " Type: " + buildingType + " Level: " + buildingLevel + " Id: " + buildingId);
    
    var buildingAttempts = 0;
    var loaded_bQ = t["bQ_" + cityId];

    if (typeof Seed.queue_con['city' + cityId][0] != 'undefined') 
    {
      var current_construction_pos = Seed.queue_con['city' + cityId][0][2];
    } 
    else 
    {
      var current_construction_pos = "";
    }

    if (loaded_bQ.length == 0 && current_construction_pos != "" ) 
    { //check anyway if there is currently build in progess for this specific building
      if (current_construction_pos != 'NaN' && current_construction_pos == buildingId) 
      {
        buildingLevel += 1;
      }
    } 
    else 
    {
      if (current_construction_pos != "" && current_construction_pos == buildingId) 
      {
        buildingLevel += 1;
      }
      
      for (var i = 0; i < loaded_bQ.length; i++) 
      { // check if there are already queue items for this building or the building is currently building
        var loadedCity = loaded_bQ[i].cityId;
        var loadedSlot = loaded_bQ[i].buildingPos;

        if (loadedSlot == buildingPos && loadedCity == cityId) 
        {
          buildingLevel += 1;
        }

        if (loaded_bQ[i].buildingMode == 'destruct' && loadedSlot == buildingPos && loadedCity == cityId) { // check if destrcution is already in queue
          t.modalmessage(translate("Destruction already in Queue!"));
          return;
        }
      }
    }

    if (t.currentBuildMode == "build") {
      if (buildingLevel >= 9) {
        t.modalmessage(translate('Due to building requirements (DI), buildings above level 9\nshould be manualy built.'));
        return;
      }

      var buildingMode = "build";
      var result = t.calculateQueueValues(cityId, buildingLevel, buildingType, buildingMode);
      var buildingMult = result[0];
      var buildingTime = result[1];
      var queueId = loaded_bQ.length;
      t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode);
      t._addTab(queueId, cityId, buildingType, buildingTime, buildingLevel, buildingAttempts, buildingMode);
    }
    if (t.currentBuildMode == "max") {
      var buildingMode = "build";
      for (var bL = buildingLevel; bL <9; bL++) {
        var queueId = loaded_bQ.length;
        var result = t.calculateQueueValues(cityId, bL, buildingType, buildingMode);
        var buildingMult = result[0];
        var buildingTime = result[1];
        queueId = queueId ;
        t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult, buildingMode);
        t._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
      }
    }
    if (t.currentBuildMode == "destruct") {
      var buildingMode = "destruct";
      var result = t.calculateQueueValues(cityId, buildingLevel, buildingType, buildingMode);
      var buildingMult = result[0];
      var buildingTime = result[1];
      var queueId = loaded_bQ.length;
      t.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode);
      t._addTab(queueId, cityId, buildingType, buildingTime, buildingLevel, buildingAttempts, buildingMode);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  calculateQueueValues: function (cityId, buildingLevel, buildingType, buildingMode) 
  {
    var t = Tabs.build;
    var now = unixTime();

    if (buildingMode == 'build') 
    {
      var buildingMult = Math.pow(2, buildingLevel);
    } 

    if (buildingMode == 'destruct') 
    {
      var buildingMult = Math.pow(2, buildingLevel - 2);
    }
        
    var knights = Seed.knights["city" + cityId];

    if (knights) 
    {
      var polKniId = parseInt(Seed.leaders['city' + cityId].politicsKnightId);
      
      if (polKniId) 
      {
        var polValue = parseInt(Seed.knights['city' + cityId]['knt' + polKniId].politics);
        var polBoost = parseInt(Seed.knights['city' + cityId]['knt' + polKniId].politicsBoostExpireUnixtime);
        
        if ((polBoost - now) > 0) 
        {
          polValue = parseInt(polValue * 1.25);
        }
      } 
      else 
      {
        polValue = 0;
      }
    } 
    else 
    {
      polValue = 0;
    }
        
    var buildingTime = unsafeWindow.buildingcost["bdg" + buildingType][7] * buildingMult;

    if (parseInt(buildingType) < 6 && parseInt(buildingType) > 0 && buildingMult == 1) 
    {
        buildingTime = 15;
    }

    if (buildingMode == 'build') 
    {
      buildingTime = parseInt(buildingTime / (1 + 0.005 * polValue + 0.1 * parseInt(Seed.tech.tch16)));
    }

    if (buildingMode == 'destruct') 
    {
      buildingTime = buildingTime / (1 + 0.005 * polValue + 0.1 * parseInt(Seed.tech.tch16));
      if (buildingTime % 1 > 0) 
      {
        buildingTime = parseInt(buildingTime);
      }
    }
    
    var result = new Array(buildingMult, buildingTime);
    return result;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  bot_gethelp: function (f, currentcityid) 
  {
    var t = Tabs.build;
    var city = t.getCityNameById(currentcityid);
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.bid = f;
    params.ctrl = 'AskForHelp';
    params.action = 'getHelpData';
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      
      onSuccess: function (rslt) 
      {
        CheckUpdateSeed(rslt);
          
        unsafeWindow.handleHelpCallback (rslt.data);
      },
      
      onFailure: function (rslt) 
      {
        t.bot_gethelp (f, currentcityid);
        return;
      },
    });

    // disable fb posts for now
    // TODO : if we reintroduce we should add in the time delay again to not post for short builds 30mins?
    if (false) 
    {
      var a = Seed.queue_con["city" + currentcityid];
      var e = 0;
      var d = 0;
      
      for (var c = 0; c < a.length; c++) 
      {
        if (parseInt(a[c][2]) == parseInt(f)) 
        {
          e = parseInt(a[c][0]);
          d = parseInt(a[c][1]);
          break
        }
      }
      
      var b = new Array();
      b.push(["REPLACE_LeVeLbUiLdInG", d]);
      b.push(["REPLACE_BuIlDiNgNaMe", unsafeWindow.buildingcost["bdg" + e][0]]);
      b.push(["REPLACE_LeVeLiD", d]);
      b.push(["REPLACE_AsSeTiD", f]);
      var g = function(h, i) {
        unsafeWindow.continuation_95(h, i);
        if (!h) {
          var j = d > 1 ? CM.SpeedUpType.upgrade : CM.SpeedUpType.build;
          CM.ClientSideCookieManager.setCookie(j, false)
        }
      };
      
      unsafeWindow.common_postToProfile("95", unsafeWindow.Object.cloneFeed(unsafeWindow.template_data_95), unsafeWindow.Object.cloneFeed(unsafeWindow.actionlink_data_95), g, b)
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addQueueItem: function (cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode) 
  {
    var t = Tabs.build;
    var lbQ = t["bQ_" + cityId];
    
    lbQ.push({
      cityId:       cityId,
      buildingPos:    buildingPos,
      buildingType:     buildingType,
      buildingId:     buildingId,
      buildingTime:     buildingTime,
      buildingLevel:    buildingLevel,
      buildingAttempts:   buildingAttempts,
      buildingMult:     buildingMult,
      buildingMode:     buildingMode
    });
    
    t.modifyTotalTime(cityId, 'increase', buildingTime); //adjust total Time
  },

  modalmessage: function(message)
  {
    var t = Tabs.build;
    var timeout = 10000;
    var content = translate("autoclose after 10sec")+"...<br><br>"
    content += message;
    unsafeWindow.Modal.showAlert(content);
    window.setTimeout('unsafeWindow.Modal.hideModal();', timeout);
  },

  modifyTotalTime: function (cityId, type, buildingTime) 
  {
    var t = Tabs.build;
    var element = document.getElementById('pbbuildcount_' + cityId);
    var currentCount = parseInt(element.innerHTML);

    if (type == "increase") {
      t['totalTime_' + cityId] = t['totalTime_' + cityId] + buildingTime;
      var currentCount = currentCount + 1;
    }

    if (type == "decrease") {
      t['totalTime_' + cityId] = t['totalTime_' + cityId] - buildingTime;
      var currentCount = currentCount - 1;
    }

    element.innerHTML = currentCount;
    document.getElementById('pbbuildtotal_' + cityId).innerHTML = timestr(t['totalTime_' + cityId]);
  },

  hide: function()
  {
    var t = Tabs.build;
    //unsafeWindow.buildslot = t.koc_buildslot; // restore original koc function
  },

  onUnload: function()
  {
    var t = Tabs.build;
    for (var i = 0; i < Cities.cities.length; i++) {
      //t["bQ_" + Cities.cities[i].id] = []; //clean up if needed

      if (!ResetAll) {
        GM_setValue('bQ_' + getServerId() + '_' + Cities.cities[i].id, JSON2.stringify((t["bQ_" + Cities.cities[i].id])));
      }
    }
    t.saveBuildStates();
  },

  _addTab: function(queueId, cityId, buildingType, buildingTime, buildingLevel, buildingAttempts, buildingMode)
  {
    var t = Tabs.build;
    var row = document.getElementById('pbCityQueueContent').insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = queueId;

    if (buildingMode == "destruct") {
      row.insertCell(1).innerHTML = '<img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/bonus_att.png">';
    }
    else 
    {
      row.insertCell(1).innerHTML = '<img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/bonus_prod.png">';
    }

    row.insertCell(2).innerHTML = unsafeWindow.buildingcost['bdg' + buildingType][0];
    row.insertCell(3).innerHTML = timestr(buildingTime);

    if (buildingMode == "destruct") {
      row.insertCell(4).innerHTML = 0;
    } 
    else 
    {
      row.insertCell(4).innerHTML = buildingLevel + 1; // => target Level
    }

    row.insertCell(5).innerHTML = buildingAttempts;
    row.insertCell(6).innerHTML = '<a class="button20" id="queuecancel_' + queueId + '"><span>Cancel</span></a>';
    
    document.getElementById('queuecancel_' + queueId).addEventListener('click', function()
    {
      t.cancelQueueElement(queueId, cityId, buildingTime, true);
    }, false);
  },

  cancelQueueElement: function(queueId, cityId, buildingTime, showQueue)
  {
    var t = Tabs.build;
    var queueId = parseInt(queueId);
    t["bQ_" + cityId].splice(queueId, 1);
    t.modifyTotalTime(cityId, 'decrease', buildingTime); //adjust total Time  
    
    if (showQueue == true) 
    {
      t.showBuildQueue(cityId, false);
    }
  },

  showBuildQueue: function(cityId, focus)
  {
    var t = Tabs.build;
    clearTimeout (t.timer);
    var popBuildQueue = null;
    var cityName = t.getCityNameById(cityId);

    if (t.popBuildQueue == null) {
        t.popBuildQueue = new pbPopup('pbbuild_' + cityId, 0, 0, 350, 500, true, function() {clearTimeout (t.timer);});
    }

    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbTabPad" id="pbCityQueueContent">';       
    t.popBuildQueue.getMainDiv().innerHTML = '</table></div>' + m;
    t.popBuildQueue.getTopDiv().innerHTML = '<TD width="200px"><B>'+translate("Build Queue of")+' ' + cityName + '</b></td><TD><INPUT id=pbOptimizeByTime type=submit value="'+translate("Optimize by Time")+'"></td>';
    t.paintBuildQueue(cityId);

    if (focus) {
      t.popBuildQueue.show(true);
    }

    document.getElementById('pbOptimizeByTime').addEventListener('click', function(){t.clearBuildQueue();t.paintBuildQueue(cityId, true);}, false);
    t.timer = setTimeout (function() {t.showBuildQueue(cityId, false)}, 45000);  
  },
    paintBuildQueue: function(cityId, optimize){
        var t = Tabs.build;
        var lbQ = t["bQ_" + cityId];
    if (optimize == true) {
      lbQ.sort(function(a,b){return a.buildingTime - b.buildingTime});
    }
    t["bQ_" + cityId] = lbQ;
    for (var i = 0; i < lbQ.length; i++) {
      var queueId = i;
      t._addTab(queueId, lbQ[i].cityId, lbQ[i].buildingType, lbQ[i].buildingTime, lbQ[i].buildingLevel, lbQ[i].buildingAttempts, lbQ[i].buildingMode);
        }
    },
  clearBuildQueue: function() {
      var t = Tabs.build;
    var table = document.getElementById('pbCityQueueContent');
    var rows = table.rows;
    while(rows.length)
      table.deleteRow(rows.length-1);
  },
    getCurrentCityId: function(){ // TODO maybe move as global function to the core application
        if (!unsafeWindow.currentcityid)
            return null;
        return unsafeWindow.currentcityid;
    },
    saveBuildStates: function(){
    var t = Tabs.build;
        var serverID = getServerId();
        GM_setValue('buildStates_' + serverID, JSON2.stringify(t.buildStates));
    },
    readBuildStates: function(){
        var t = Tabs.build;
        var serverID = getServerId();
        s = GM_getValue('buildStates_' + serverID);
        if (s != null) {
            states = JSON2.parse(s);
            for (k in states)
                t.buildStates[k] = states[k];
        }
    },
    toggleStateRunning: function(obj){
    var t = Tabs.build;
        if (t.buildStates.running == true) {
            t.buildStates.running = false;
            t.saveBuildStates();
            obj.value = translate("Auto Build = OFF");
        }
        else {
            t.buildStates.running = true;
            t.saveBuildStates();
            obj.value = translate("Auto Build = ON");
        }
    },
    toggleStateMode: function(obj){
    var t = Tabs.build;
        if (obj.value == translate('Build Mode = OFF')) {
      unsafeWindow.buildslot = t.bot_buildslot; // overwrite original koc function
      var guardian = document.getElementById('citymap').getElementsByClassName('bldg_guardian_0');
      if(guardian.length >0)
        guardian[0].addEventListener('click', t.bot_buildguardian, false);
            obj.value = translate("Build Mode = ON");
        }
        else {
      unsafeWindow.buildslot = t.koc_buildslot; // restore original koc function
      var guardian = document.getElementById('citymap').getElementsByClassName('bldg_guardian_0');
      if(guardian.length >0)
        guardian[0].removeEventListener('click', t.bot_buildguardian, false);
      obj.value = translate("Build Mode = OFF");
        }
    },
  getCityNameById: function (cityId) {
    return Cities.byID[cityId].name;    
  },
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Search
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Search = {
  tabOrder : 50,
  myDiv : null,
  MapAjax : new CMapAjax(),
  MAX_SHOW_WHILE_RUNNING : 250,
  popFirst : true,
  SearchList : [],
  
  init : function (div){
    var t = Tabs.Search;
    var Provinces = {1:{'name':"Tintagel",'x':75,'y':75},
        2:{'name':"Cornwall",'x':225,'y':75},
        3:{'name':"Astolat",'x':375,'y':75},
        4:{'name':"Lyonesse",'x':525,'y':75},
        5:{'name':"Corbenic",'x':675,'y':75},

        6:{'name':"Paimpont",'x':75,'y':225},
        7:{'name':"Cameliard",'x':225,'y':225},
        8:{'name':"Sarras",'x':375,'y':225},
        9:{'name':"Canoel",'x':525,'y':225},
        10:{'name':"Avalon",'x':675,'y':225},

        11:{'name':"Carmathen",'x':75,'y':375},
        12:{'name':"Shallot",'x':225,'y':375},
        //13:{'name':"-------",'x':375,'y':375},
        14:{'name':"Cadbury",'x':525,'y':375},
        15:{'name':"Glastonbury",'x':675,'y':375},

        16:{'name':"Camlamn",'x':75,'y':525},
        17:{'name':"Orkney",'x':225,'y':525},
        18:{'name':"Dore",'x':375,'y':525},
        19:{'name':"Logres",'x':525,'y':525},
        20:{'name':"Caerleon",'x':675,'y':525},

        21:{'name':"Parmenie",'x':75,'y':675},
        22:{'name':"Bodmin Moor",'x':225,'y':675},
        23:{'name':"Cellwig",'x':375,'y':675},
        24:{'name':"Listeneise",'x':525,'y':675},
        25:{'name':"Albion",'x':675,'y':675}};
    t.selectedCity = Cities.cities[0];
    t.myDiv = div;
    
    m = '<DIV class=pbentry><TABLE width=100% class=pbTab><TR><TD class=pbDetLeft>'+translate("Search for")+': </td><TD width=99%>';
    m += htmlSelector ({0:translate("Barb Camp"), 1:translate("Wilderness"), 2:translate("Cities")}, null, 'id=pasrcType');
  m += '&nbsp; &nbsp; &nbsp; <span class=pbDetLeft>'+translate("Search style")+': &nbsp;';
  m += htmlSelector({square:translate("Square"), circle:translate("Circle")}, Options.srcdisttype, 'id=pbsrcdist');
    m += '</span></td></tr><TR><TD class=pbDetLeft>'+translate("At")+': </td><TD class=xtab>X=<INPUT id=pasrchX type=text\> &nbsp;Y=<INPUT id=pasrchY type=text\>\
      &nbsp; '+translate("Radius")+': <INPUT id=pasrcDist size=3 value=10 /> &nbsp; <SPAN id=paspInXY></span></tr>\
      <TR><TD class=pbDetLeft>Or:</td><TD>'+translate("Search entire province")+': <select id="provinceXY"><option>--'+translate("provinces")+'--</option>';
    for (var i in Provinces)
      m += '<option value="'+i+'">'+Provinces[i].name+'</option>';
    m += '</select></td></tr>';
    m += '<TR><TD colspan=2 align=center><INPUT id=pasrcStart type=submit value="'+translate("Start Search")+'"/></td></tr>';
    m += '</table></div>\
        <DIV id="pasrcResults" style="height:400px; max-height:400px;"></div>';
    
    t.myDiv.innerHTML = m;
    var psearch = document.getElementById ("pasrcType");
    new CdispCityPicker ('pasrchdcp', document.getElementById ('paspInXY'), true, t.citySelNotify).bindToXYboxes(document.getElementById ('pasrchX'), document.getElementById ('pasrchY'));
    document.getElementById ('provinceXY').addEventListener ('click', function() {
        if (this.value >= 1) {
          document.getElementById ('pasrchX').value = Provinces[this.value].x;
          document.getElementById ('pasrchY').value = Provinces[this.value].y;
          document.getElementById ('pasrcDist').value = '75';
        }
      }, false);
  document.getElementById('pbsrcdist').addEventListener ('change', function (){
      Options.srcdisttype = document.getElementById('pbsrcdist').value;
      saveOptions();
      }, false);
    document.getElementById ('pasrcStart').addEventListener ('click', t.clickedSearch, false);
    document.getElementById ('pasrchX').addEventListener ('keydown', t.e_coordChange, false);
    document.getElementById ('pasrchY').addEventListener ('keydown', t.e_coordChange, false);
    document.getElementById ('pasrcDist').addEventListener ('keydown', t.e_coordChange, false);
    document.getElementById ('pasrchY').addEventListener ('change', t.e_coordChange, false);
    document.getElementById ('pasrchY').addEventListener ('change', t.e_coordChange, false);
    unsafeWindow.pbSearchLookup = t.clickedLookup;  
    unsafeWindow.pbSearchScout = t.clickedScout;
    unsafeWindow.pbExportToRaid = t.ExportToRaid;
  },

  e_coordChange : function(){
    document.getElementById ('provinceXY').selectedIndex = 0;
  },
  
  hide : function (){
  },

  show : function (cont){
  },

  citySelNotify : function (city){
    var t = Tabs.Search;
    t.selectedCity = city;
    t.JumpCity(city.name);
  },
  
  JumpCity:function(city) {
    var t = Tabs.Search;
  for (i=0;i<Seed.cities.length;i++) {
    if (Seed.cities[i][1]==city) var cityNum=i;
  }
  cityNum++;
  var obj = document.getElementById('citysel_'+cityNum);
    return t.ClickWin(window,obj,'click');
  },
  
  ClickWin:function(win,obj,evtName) {
    var evt = win.document.createEvent("MouseEvents");
    evt.initMouseEvent(evtName, true, true, win,
      0, 0, 0, 0, 0, false, false, false, false, 0, null);
    return !obj.dispatchEvent(evt);
  },
  
  helpPop : function (){
       var helpText = translate("Raids_Help");
       helpText += '<A target="_tab" href="http://koc.wikia.com/wiki/Barbarian_Camps">A lot more can be found on Koc Wikia</a>';
       helpText += '<TABLE><TR><TD>Lvl</td><TD>Troops</td></tr>';
       helpText += '<TR><TD>1</td><TD>500 Supply Troops + 500 Archers</td></tr>';
       helpText += '<TR><TD>2</td><TD>500 Supply Troops + 2500 Archers</td></tr>';
       helpText += '<TR><TD>3</td><TD>500 Supply Troops + 5000 Archers</td></tr>';
       helpText += '<TR><TD>4</td><TD>500 Supply Troops + 7500 Archers</td></tr>';
       helpText += '<TR><TD>5</td><TD>15000 Archers</td></tr>';
       helpText += '<TR><TD>5</td><TD>12000 Archers IF Level 10 fletching and Level 9 Featherweight</td></tr>';
       helpText += '<TR><TD>6</td><TD>25000 Archers IF Level 9 fletching</td></tr>';
       helpText += '<TR><TD>6</td><TD>22000 Archers IF Level 10 fletching</td></tr>';
       helpText += '<TR><TD>7</td><TD>45000 Archers IF Level 10 fletching</td></tr>';
       helpText += '<TR><TD>7</td><TD>44000 Archers IF Level 10 fletching and knight 69+</td></tr>';
       helpText += '<TR><TD>7</td><TD>40000 Archers IF Level 10 fletching and knight 94+</td></tr>';
       helpText += '<TR><TD>8</td><TD>28000 Ballista WITH Level 10 fletching and Knight 91+</td></tr>';
       helpText += '<TR><TD>9</td><TD>56000 Ballista WITH Level 10 fletching and Knight 98+</td></tr>';
       helpText += '<TR><TD>10</td><TD>125000 Catapults (500 Catapults loss!)</td></tr></tr></table>';
  
  
       var pop = new pbPopup ('giftHelp', 0, 0, 425, 375, true);
       pop.centerMe (mainPop.getMainDiv());  
       pop.getMainDiv().innerHTML = helpText;
       pop.getTopDiv().innerHTML = '<CENTER><B>Power Bot '+translate("Help")+': '+translate("Raids")+'</b></center>';
       pop.show (true);
     },
     
     
  opt : {},
  selectedCity : null,
  searchRunning : false,
  tilesSearched : 0,
  tilesFound : 0,
  curX : 0,
  curY : 0,
  lastX : 0,
  firstX : 0,
  firstY : 0,
  lastY : 0,

  clickedSearch : function (){
    var t = Tabs.Search;

    if (t.searchRunning){
      t.stopSearch (translate('SEARCH CANCELLED!'));
      return;
    }
    t.opt.searchType = document.getElementById ('pasrcType').value;
    t.opt.startX = parseInt(document.getElementById ('pasrchX').value);
    t.opt.startY = parseInt(document.getElementById ('pasrchY').value);
    t.opt.maxDistance = parseInt(document.getElementById ('pasrcDist').value);
    t.opt.searchShape = Options.srcdisttype;
    errMsg = '';

    if (isNaN (t.opt.startX) ||t.opt.startX<0 || t.opt.startX>749)
      errMsg = "X "+translate("must be between 0 and 749")+"<BR>";
    if (isNaN (t.opt.startY) ||t.opt.startY<0 || t.opt.startY>749)
      errMsg += "Y "+translate("must be between 0 and 749")+"<BR>";
    if (isNaN (t.opt.maxDistance) ||t.opt.maxDistance<1 || t.opt.maxDistance>75)
      errMsg += translate("Radius (distance) must be between")+" 1 +"+translate("and")+" 75<BR>";
    if (errMsg != ''){
      document.getElementById('pasrcResults').innerHTML = '<FONT COLOR=#660000>'+translate("ERROR")+':</font><BR><BR>'+ errMsg;
      return;
    }

    t.searchRunning = true;
    document.getElementById ('pasrcStart').value = translate('Stop Search');
    m = '<DIV class=pbStat><TABLE width=100% cellspacing=0><TR><TD class=xtab width=125><DIV id=pastatSearched></div></td>\
        <TD class=xtab align=center><SPAN style="white-space:normal" id=pastatStatus></span></td>\
        <TD class=xtab align=right width=125><DIV id=pastatFound></div></td></tr></table></div>\
          <TABLE width=100%><TR valign=top>\
            <TD width=99% style="max-width:50px"><DIV id=padivOutTab style="height:380px; max-height:380px; overflow-y:auto;"></div></td>\
            <TD align=center valign=middle><A id=pbAhideShow style="text-decoration:none; cursor:pointer;"><DIV style="width:1em; border:1px solid red; padding:10px 2px; background-color:#fee"><SPAN id=spanHideShow> '+translate("H I D E")+'</span><BR><BR> '+translate("L<BR>I<BR>S<BR>T<BR><BR> O<BR>P<BR>T<BR>I<BR>O<BR>N<BR>S")+' </div></a></td>\
            <TD width=100% height=100% style="background:#e0e0f0; height:100%; padding:5px"><DIV id=padivOutOpts></div></td>\
          </table>';
      
    document.getElementById('pasrcResults').innerHTML = m;
    if (t.opt.searchType == 0)
      var typeName = translate('Barbarians');
    else if (t.opt.searchType == 1)
      var typeName = translate('Wildernesses');
    else
      var typeName = translate('Cities');
    if (t.opt.searchShape == 'square')
      var distName = translate('Distance');
    else
      var distName = translate('Radius');
    m = '<CENTER><B>'+translate("Search for")+' '+ typeName +'<BR>\
        '+translate("Center")+': '+ t.opt.startX +','+ t.opt.startY +'  &nbsp; '+ distName +': '+ t.opt.maxDistance +'<BR></center>\
        <DIV class=pbentry><TABLE cellspacing=0 width=100%><TR align=center><TD class=xtab colspan=10><B>'+translate("LIST OPTIONS")+':</b><BR></td></tr>';
        
    if (t.opt.searchType == 1 || t.opt.searchType == 0) {
      m += '<TR><TD class=xtab align=right>'+translate("Min")+". "+translate("level to show")+':</td><TD class=xtab> <INPUT id=pafilMinLvl size=2 value='+ Options.srcMinLevel +' /></td></tr>\
        <TR><TD class=xtab align=right>'+translate("Max")+". "+translate("level to show")+':</td><TD class=xtab> <INPUT id=pafilMaxLvl size=2 value='+ Options.srcMaxLevel +' /></td></tr>';
    }
    if (t.opt.searchType == 1){
      m += '<TR><TD class=xtab align=right>'+translate("Wilderness Type")+':</td><TD class=xtab><SELECT id=pafilWildType>';
      m += htmlOptions ( {1:translate('Grassland/Lake'), 3:translate('Woodlands'), 4:translate('Hills'), 5:translate('Mountain'), 6:translate('Plain'), 8:translate('Dark Forest'), 0:translate('ALL')}, Options.wildType );
    m+= '</select></td></tr>';
    // m+= '<TR><TD class=xtab align=right>Glassland/Lake:</td><TD class=xtab><INPUT name=pbfil id=pafilGrass type=CHECKBOX '+ (Options.GrassOnly?' CHECKED':'') +'\><td></tr>';
    // m+= '<TR><TD class=xtab align=right>Woodlands:</td><TD class=xtab><INPUT name=pbfil id=pafilWood type=CHECKBOX '+ (Options.WoodOnly?' CHECKED':'') +'\><td></tr>';
    // m+= '<TR><TD class=xtab align=right>Hills:</td><TD class=xtab><INPUT name=pbfil id=pafilHill type=CHECKBOX '+ (Options.HillOnly?' CHECKED':'') +'\><td></tr>';
    // m+= '<TR><TD class=xtab align=right>Mountain:</td><TD class=xtab><INPUT name=pbfil id=pafilMount type=CHECKBOX '+ (Options.MountOnly?' CHECKED':'') +'\><td></tr>';
    // m+= '<TR><TD class=xtab align=right>Plain:</td><TD class=xtab><INPUT name=pbfil id=pafilPlain type=CHECKBOX '+ (Options.PlainOnly?' CHECKED':'') +'\><td></tr>';
    // m+= '<TR><TD class=xtab align=right>All:</td><TD class=xtab><INPUT name=pbfil id=pafilAll type=CHECKBOX '+ (Options.srcAll?' CHECKED':'') +'\><td></tr>';
      m += '</select></td></tr><TR><TD class=xtab align=right>'+translate("Unowned Only")+':</td><TD class=xtab><INPUT id=pafilUnowned type=CHECKBOX '+ (Options.unownedOnly?' CHECKED':'') +'\><td></tr>';
    }
   if (t.opt.searchType == 1 || t.opt.searchType == 0) {
        m+= '<TR><TD class=xtab align=right>Sort By:</td><TD class=xtab><SELECT id=pafilSortBy>\
          <OPTION value="level" '+ (Options.srcSortBy=='level'?'SELECTED':'')  +'>'+translate("Level")+'</option>\
          <OPTION value="dist" '+ (Options.srcSortBy=='dist'?'SELECTED':'')  +'>'+translate("Distance")+'</option>\
      </select></td></tr>\
      <TR><TD class=xtab align=right>'+translate("Coordinates only")+':</td><TD class=xtab><INPUT type=checkbox id=pacoordsOnly \></td></tr>\
      </table></div><BR><SPAN id=pasrchSizeWarn></span><DIV id=pbSrcExp></div>';
    } else {
    m+= '</select></td></tr><TR><TD class=xtab align=right>'+translate("Misted")+':</td><TD class=xtab><INPUT name=pbfil id=pafilMisted type=CHECKBOX '+ (Options.mistedOnly?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("Hostile")+':</td><TD class=xtab><INPUT name=pbfil id=pafilHostile type=CHECKBOX '+ (Options.hostileOnly?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("Friendly")+':</td><TD class=xtab><INPUT name=pbfil id=pafilFriendly type=CHECKBOX '+ (Options.friendlyOnly?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("Allied")+':</td><TD class=xtab><INPUT name=pbfil id=pafilAllied type=CHECKBOX '+ (Options.alliedOnly?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("Neutral")+':</td><TD class=xtab><INPUT name=pbfil id=pafilNeutral type=CHECKBOX '+ (Options.neutralOnly?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("Unallianced")+':</td><TD class=xtab><INPUT name=pbfil id=pafilunAllied type=CHECKBOX '+ (Options.unalliedOnly?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("All")+':</td><TD class=xtab><INPUT name=pbfil id=pafilAll type=CHECKBOX '+ (Options.srcAll?' CHECKED':'') +'\><td></tr>';
    m+= '<TR><TD class=xtab align=right>'+translate("Sort By")+':</td><TD class=xtab><SELECT id=pafilSortBy>\
          <OPTION value="might" '+ (Options.srcSortBy=='might'?'SELECTED':'')  +'>'+translate("Might")+'</option>\
             <OPTION value="dist" '+ (Options.srcSortBy=='dist'?'SELECTED':'')  +'>'+translate("Distance")+'</option>\
        </select></td></tr>\
    <TR><TD class=xtab align=right>'+translate("Min")+" "+translate("might")+':</td><TD class=xtab><INPUT type=text id=paminmight size=6 value='+ Options.minmight +'>\
        <TR><TD class=xtab align=right>'+translate("Coordinates only")+':</td><TD class=xtab><INPUT type=checkbox id=pacoordsOnly \></td></tr>\
        </table></div><BR><SPAN id=pasrchSizeWarn></span><DIV id=pbSrcExp></div>';
  
  }
    document.getElementById('padivOutOpts').innerHTML = m;
   if (t.opt.searchType == 1 || t.opt.searchType == 0) {
    document.getElementById('pafilMinLvl').addEventListener ('change', function (){
      Options.srcMinLevel = document.getElementById('pafilMinLvl').value;
      saveOptions();
      t.dispMapTable ();
      }, false);
    document.getElementById('pafilMaxLvl').addEventListener ('change', function (){
      Options.srcMaxLevel = document.getElementById('pafilMaxLvl').value;
      saveOptions();
      t.dispMapTable ();
      }, false);
    }
    document.getElementById('pafilSortBy').addEventListener ('change', function (){
      Options.srcSortBy = document.getElementById('pafilSortBy').value;
      saveOptions();
      t.dispMapTable ();
      }, false);
    document.getElementById('pacoordsOnly').addEventListener ('change', function (){ t.dispMapTable (); }, false);
    if (t.opt.searchType == 1){
      document.getElementById('pafilWildType').addEventListener ('change', function (){
        Options.wildType = document.getElementById('pafilWildType').value;
        saveOptions();
        t.dispMapTable ();
        }, false);
      document.getElementById('pafilUnowned').addEventListener ('change', function (){
        Options.unownedOnly = (document.getElementById('pafilUnowned').checked);
        saveOptions();
        t.dispMapTable ();
        }, false);
    }
  if (t.opt.searchType == 2){
    document.getElementById('pafilMisted').addEventListener ('change', function (){
        Options.mistedOnly = (document.getElementById('pafilMisted').checked);
    if(!Options.mistedOnly){
      document.getElementById('pafilAll').checked = false;
      Options.srcAll = Options.mistedOnly;
    }
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('pafilHostile').addEventListener ('change', function (){
        Options.hostileOnly = (document.getElementById('pafilHostile').checked);
    if(!Options.hostileOnly){
      document.getElementById('pafilAll').checked = false;
      Options.srcAll = Options.hostileOnly;
    }
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('pafilFriendly').addEventListener ('change', function (){
        Options.friendlyOnly = (document.getElementById('pafilFriendly').checked);
    if(!Options.friendlyOnly){
      document.getElementById('pafilAll').checked = false;
      Options.srcAll = Options.friendlyOnly;
    }
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('pafilAllied').addEventListener ('change', function (){
        Options.alliedOnly = (document.getElementById('pafilAllied').checked);
    if(!Options.alliedOnly){
      document.getElementById('pafilAll').checked = false;
      Options.srcAll = Options.alliedOnly;
    }
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('pafilNeutral').addEventListener ('change', function (){
        Options.neutralOnly = (document.getElementById('pafilNeutral').checked);
    if(!Options.neutralOnly){
      document.getElementById('pafilAll').checked = false;
      Options.srcAll = Options.neutralOnly;
    }
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('pafilunAllied').addEventListener ('change', function (){
        Options.unalliedOnly = (document.getElementById('pafilunAllied').checked);
    if(!Options.unalliedOnly){
      document.getElementById('pafilAll').checked = false;
      Options.srcAll = Options.unalliedOnly;
    }
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('pafilAll').addEventListener ('change', function (){
        Options.srcAll = (document.getElementById('pafilAll').checked);
    for(i in document.getElementsByName('pbfil'))
      document.getElementsByName('pbfil')[i].checked = Options.srcAll;
    Options.mistedOnly=Options.hostileOnly=Options.friendlyOnly=Options.alliedOnly=Options.neutralOnly=Options.unalliedOnly=Options.srcAll;
        saveOptions();
        t.dispMapTable ();
        }, false);
    document.getElementById('paminmight').addEventListener ('change', function (){
        Options.minmight = parseIntNan(document.getElementById('paminmight').value);
        saveOptions();
        t.dispMapTable ();
        }, false);
  
  }
  
    document.getElementById('pbAhideShow').addEventListener ('click', t.hideShowClicked, false);
  
    t.mapDat = [];
    t.firstX =  t.opt.startX - t.opt.maxDistance;
    t.lastX = t.opt.startX + t.opt.maxDistance;
    t.firstY =  t.opt.startY - t.opt.maxDistance;
    t.lastY = t.opt.startY + t.opt.maxDistance;
    t.tilesSearched = 0;
    t.tilesFound = 0;
    t.curX = t.firstX;
    t.curY = t.firstY;
    var xxx = t.MapAjax.normalize(t.curX);
    var yyy = t.MapAjax.normalize(t.curY);
    document.getElementById ('pastatStatus').innerHTML = translate('Searching at ')+ xxx +','+ yyy;
    setTimeout (function(){t.MapAjax.request (xxx, yyy, 15, t.eventgetplayeronline)}, MAP_DELAY);
  },

  hideShowClicked : function (){
    var div = document.getElementById('padivOutOpts');
    if (div.style.display == 'none'){
      div.style.display = 'block';
      document.getElementById('spanHideShow').innerHTML = translate('H I D E');
    } else {
      div.style.display = 'none';
      document.getElementById('spanHideShow').innerHTML = translate('S H O W');
    }
  },
  
  dispMapTable : function (){
    var tileNames = ['Barb Camp', 'Grassland', 'Lake', 'Woodlands', 'Hills', 'Mountain', 'Plain', null, 'Dark Forest' ];
    var t = Tabs.Search;
    var coordsOnly = document.getElementById('pacoordsOnly').checked;
    if (DEBUG_SEARCH) DebugTimer.start();
     function mySort(a, b){
      if (Options.srcSortBy == 'level'){
        if ((x = a[4] - b[4]) != 0)
          return x;
      }
    if (Options.srcSortBy == 'might'){
        if ((x = b[10] - a[10]) != 0)
          return x;
      }
      return a[2] - b[2];
    }
  
    dat = [];
    for (i=0; i<t.mapDat.length; i++){
      lvl = parseInt (t.mapDat[i][4]);
      type = t.mapDat[i][3];
      if (t.opt.searchType==2 && type==7 ) {
    if(t.mapDat[i][10] >= Options.minmight || t.mapDat[i][5])
    //if(lvl >= 12)
    if((Options.hostileOnly && t.mapDat[i][12] == 'h') ||
       (Options.mistedOnly && t.mapDat[i][5]===true) ||
       (Options.friendlyOnly && t.mapDat[i][12] == 'f') ||
       (Options.alliedOnly && t.mapDat[i][12] == 'a') ||
       (Options.neutralOnly && t.mapDat[i][12] == 'n') ||
       (Options.unalliedOnly && t.mapDat[i][12] == 'u') ||
       (Options.srcAll))
        dat.push(t.mapDat[i]);
      } else {
       if (lvl>=Options.srcMinLevel && lvl<=Options.srcMaxLevel){
        if (t.opt.searchType==0 || Options.wildType==0
        ||  (Options.wildType==1 && (type==1 || type==2))
        ||  (Options.wildType == type)){
          if (!Options.unownedOnly || t.mapDat[i][5]===false)
            dat.push (t.mapDat[i]);
        }
       }
    }
    }
    if (DEBUG_SEARCH) DebugTimer.display('SEACHdraw: FILTER');

    document.getElementById('pastatFound').innerHTML = translate('Found')+': '+ dat.length;
    if (dat.length == 0){
      m = '<BR><CENTER>'+translate("None found")+'</center>';
    } else {
      dat.sort(mySort);
      if (DEBUG_SEARCH) DebugTimer.display('SEACHdraw: SORT');
      if (coordsOnly)
        m = '<TABLE align=center id=pasrcOutTab cellpadding=0 cellspacing=0><TR style="font-weight: bold"><TD>'+translate("Location")+'</td></tr>';
      else {
      if (t.opt.searchType == 2) {
       m = '<TABLE id=pasrcOutTab class=pbSrchResults cellpadding=0 cellspacing=0><TR style="font-weight: bold"><TD>'+translate("Loc")+'</td><TD align=right>'+translate("Dist")+'</td><TD>'+translate("Player")+'</td><TD align=right>'+translate("Might")+'</td><TD>'+translate("Alliance")+'</td><TD>'+translate("Online")+'</td><TD></td></tr>';
    } else {
      m = '<TABLE id=pasrcOutTab cellpadding=0 cellspacing=0><TR style="font-weight: bold"><TD>'+translate("Location")+'</td><TD style="padding-left: 10px">'+translate("Distance")+'</td><TD style="padding-left: 10px;">'+translate("Lvl")+'</td><TD width=100px> &nbsp; '+translate("Type")+'</td><TD></td><TD>'+translate("Export to Raid")+'</td></tr>';
    }
  }
      var numRows = dat.length;
      if (numRows > t.MAX_SHOW_WHILE_RUNNING && t.searchRunning){
        numRows = t.MAX_SHOW_WHILE_RUNNING;
        document.getElementById('pasrchSizeWarn').innerHTML = '<FONT COLOR=#600000>'+translate('NOTE: Table only shows ')+ t.MAX_SHOW_WHILE_RUNNING +' of '+ dat.length +translate(' results until search is complete')+'.</font>';
      }
      for (i=0; i<numRows; i++){
        m += '<TR><TD><DIV onclick="pbGotoMap('+ dat[i][0] +','+ dat[i][1] +')"><A>'+ dat[i][0] +','+ dat[i][1] +'</a></div></td>';
        if (coordsOnly) {
          m += '</tr>';
        } else {
          if (t.opt.searchType == 2) { // city search
            m += '<TD align="right" >'+ dat[i][2].toFixed(2) +'</td>';
            if (dat[i][5])
              m += '<TD colspan=4>* '+translate("MISTED")+' * &nbsp; &nbsp; <SPAN onclick="pbSearchScout('+ dat[i][0] +','+ dat[i][1] +');return false;"><A>'+translate("Scout")+'</a></span></td></tr>';
            else{
              var allStyle = '';
              if (dat[i][12]=='f')
                allStyle = 'class=pbTextFriendly';
              else if (dat[i][12]=='h')
                allStyle = 'class=pbTextHostile';
              m += '<TD>'+ dat[i][9]+'</td><TD align=right>'+ dat[i][10] +'</td><TD><SPAN '+ allStyle +'>'+ dat[i][11]+'</span></td><TD>'+(dat[i][13]?'<SPAN class=boldDarkRed>'+translate("ONLINE")+'</span>':'')+'</td><TD><A onclick="pbSearchLookup('+ dat[i][7] +')">'+translate("Lookup")+'</a></td></tr>';
            }
      } else {
          m += '<TD align=right  valign="top">'+ dat[i][2].toFixed(2) +' &nbsp; </td><TD align=right>'+ dat[i][4] +'</td><TD> &nbsp; '+ tileNames[dat[i][3]]
            +'</td><TD  valign="top">'+ (dat[i][5]?(dat[i][6]!=0?' <A onclick="pbSearchLookup('+dat[i][6]+')">'+translate("OWNED")+'</a>':'<A onclick="pbSearchScout('+ dat[i][0] +','+ dat[i][1] +');return false;">'+translate("MISTED")+'</a>'):'') +'</td>';
          if (t.opt.searchType == 0) m+= '<TD align=center  valign="top"><A onclick="pbExportToRaid('+ dat[i][0]+','+dat[i][1] +')">'+translate("Export")+'</a></td>';
          m+='</tr>';
      }
    }
      
       }
      m += '</table>';
    }
    document.getElementById('padivOutTab').innerHTML = m;
    dat = null;
    if (DEBUG_SEARCH) DebugTimer.display('SEACHdraw: DRAW');
  },

  mapDat : [],

  stopSearch : function (msg)
  {
    var t = Tabs.Search;
    document.getElementById ('pastatStatus').innerHTML = '<FONT color=#ffaaaa>'+ msg +'</font>';
    document.getElementById ('pasrcStart').value = translate('Start Search');
    document.getElementById ('pasrchSizeWarn').innerHTML = '';
    
    if (t.opt.searchType==0 && document.getElementById('KOCAttackToggle')!=null)
    {    
      document.getElementById ('pbSrcExp').innerHTML = '<CENTER>'+ strButton20(translate('Export Results'), 'id=pbSrcDoExp') +'</center>';
      document.getElementById ('pbSrcDoExp').addEventListener ('click', t.exportKOCattack, false);
    }
    
    if (t.opt.searchType==2 || t.opt.searchType==1)
    {
      document.getElementById ('pbSrcExp').innerHTML = '<CENTER>'+ strButton20(translate('Generate Scout List'), 'id=pbSrcDoScout') +'</center>';
      document.getElementById ('pbSrcDoScout').addEventListener ('click', t.generateScoutList, false);
    }
    
    t.searchRunning = false;
    t.dispMapTable();
  },

  exportKOCattack : function (){
    var t = Tabs.Search;
    var bulkAdds = {};
    for (i=1; i<11; i++)
      bulkAdds['lvl'+ i] = [];
    for (i=0; i<t.mapDat.length; i++){
      var lvl = parseInt (t.mapDat[i][4]);
      if (lvl>=Options.srcMinLevel && lvl<=Options.srcMaxLevel && t.mapDat[i][3]==0)
        bulkAdds['lvl'+ lvl].push({x:t.mapDat[i][0], y:t.mapDat[i][1]});
    }
    exportToKOCattack.doExport (bulkAdds, t.selectedCity);
  },
  
  generateScoutList : function ()
  {
    var t = Tabs.Search;
    var bulkScout = [];
    
    for (i = 0 ; i < t.mapDat.length ; i++)
    {
      if(t.opt.searchType==1)
      {
        if (t.mapDat[i][3] == Options.wildType || Options.wildType==0)
          if (t.mapDat[i][4]>=Options.srcMinLevel && t.mapDat[i][4]<=Options.srcMaxLevel)
            if ((Options.unownedOnly && t.mapDat[i][5] == false) || (!Options.unownedOnly))
              bulkScout.push({x:t.mapDat[i][0], y:t.mapDat[i][1], dist:t.mapDat[i][2]});
      }
      if(t.opt.searchType==2)
      {
        if (t.mapDat[i][3] == 7)
        {
          if(t.mapDat[i][10] >= Options.minmight || t.mapDat[i][5])
          {
            if((Options.hostileOnly && t.mapDat[i][12] == 'h') ||
               (Options.mistedOnly && t.mapDat[i][5]===true) ||
               (Options.friendlyOnly && t.mapDat[i][12] == 'f') ||
               (Options.alliedOnly && t.mapDat[i][12] == 'a') ||
               (Options.neutralOnly && t.mapDat[i][12] == 'n') ||
               (Options.unalliedOnly && t.mapDat[i][12] == 'u') ||
               (Options.srcAll))
            {
              bulkScout.push({x:t.mapDat[i][0], y:t.mapDat[i][1], dist:t.mapDat[i][2]});
            }
          }
        }
      }
    }
  
    if(t.selectedCity == null)
      t.selectedCity = Cities.cities[0];
    t.ShowScoutList (bulkScout, t.selectedCity);
  },
  
  ShowScoutList : function (coordlist, city){
  var t = Tabs.Search;
  var popScout = null;
  t.scoutcity = city;
  
  if(popScout==null){
    popScout = new pbPopup ('pbsrcscout', 0,0, 350,500, true, function (){popScout.destroy(); popScout=null;});
      popScout.centerMe (mainPop.getMainDiv());  
    }
  var m = '<DIV class=pbStat>'+translate("Auto Scout Options")+'</div>';
    m += '<DIV>'+translate("Amount of Scouts to send")+': <input id=pbsrcScoutAmt value="'+Options.srcScoutAmt+'" /></div><BR>';
    m += '<DIV>'+translate("Select City")+': <span id=pbsrcScoutcitypick> </span></div><BR>';
    m += '<DIV class=pbStat>'+translate("Scout from")+' <span id=pbsrcScoutcity>'+city.name+'</span> <BR> '+translate("Total targets ")+coordlist.length+'</div>';
    m += '<DIV style="max-height:220px; overflow-y:auto;"><TABLE align=center cellpadding=0 cellspacing=0 class=pbTabPadNW><TR style="font-weight:bold; background-color:white"><TD width=15><input type=checkbox id=pbsrcScout_All /></td><TD>'+translate("Target Coords")+'</td></tr>';
    for(i=0; i<coordlist.length; i++){
      m += '<TR style="background-color:white"><TD><input type=checkbox name=pbsrcScoutCheck id="pbsrcScoutCheck_'+coordlist[i].x+'_'+coordlist[i].y+'" value="'+coordlist[i].x+'_'+coordlist[i].y+'" /></td><TD>'+coordLink(coordlist[i].x,coordlist[i].y)+'</td></tr>';
    }
    m += '</table></div>';
    m += '<BR><input type=checkbox id="pbskip">Skip targets when errors occur';
    m += '<BR><CENTER>'+ strButton20(translate('Start Scout'), 'id=pbSrcStartScout') +'</center>';
    m += '<CENTER><DIV style="width:70%; max-height:75px; overflow-y:auto;" id=pbSrcScoutResult></DIV></center>';
  popScout.getMainDiv().innerHTML = m;
  new CdispCityPicker ('pbScoutPick', document.getElementById('pbsrcScoutcitypick'), false, function(c,x,y){document.getElementById('pbsrcScoutcity').innerHTML = c.name; t.scoutcity = c; }, city.idx);
  popScout.getTopDiv().innerHTML = '<CENTER><B>Power Bot '+translate("Scout List")+'</b></center>';
  popScout.show(true);
  
  document.getElementById('pbsrcScoutAmt').addEventListener('change', function(){
    Options.srcScoutAmt = parseInt(document.getElementById('pbsrcScoutAmt').value);
    saveOptions();
  }, false);
  document.getElementById('pbsrcScout_All').addEventListener('change', function(){
    for(k in document.getElementsByName('pbsrcScoutCheck'))
      document.getElementsByName('pbsrcScoutCheck')[k].checked = document.getElementById('pbsrcScout_All').checked;
  }, false);
  document.getElementById('pbSrcStartScout').addEventListener('click', t.clickedStartScout, false);
  },
  scouting : false,
  scoutcity : null,
  doScout : function(list, city){
  var t = Tabs.Search;
  document.getElementById('pbSrcScoutResult').innerHTML = '';
  if(list.length < 1){
    document.getElementById('pbSrcScoutResult').innerHTML = '<SPAN class=boldRed>'+translate("ERROR")+': '+translate("No coords selected")+'</span>';
    t.clickedStartScout();
    return;
  }
  if(parseInt(Seed.units['city'+city.id]['unt'+3]) < Options.srcScoutAmt){
    document.getElementById('pbSrcScoutResult').innerHTML = '<SPAN class=boldRed>'+translate("ERROR")+': '+translate("No scouts available")+'</span>';
    t.clickedStartScout();
    return;
  }
  t.doScoutCount(list, city, list.length, 0);
  
  },
  doScoutCount : function(list, city, total, count)
  {
    var t = Tabs.Search;
    
    if(!t.scouting)
    {
      document.getElementById('pbSrcScoutResult').innerHTML += '<SPAN class=boldRed>'+translate("Scouting stopped by user")+'</span><BR>';
      document.getElementById('pbSrcStartScout').className = 'button20 ptButton20';
      document.getElementById('pbSrcStartScout').innerHTML = '<SPAN>'+translate("Start Scout")+'</span>';

      return;
    }

    if(total <= (count))
    {
      document.getElementById('pbSrcScoutResult').innerHTML += translate("Done")+'!<BR>';
      t.clickedStartScout();

      return;
    }
    
    if(getFreeMarchSlots(city.id) <= 0)
    {
      setTimeout(function(){t.doScoutCount(list, city, total, count)}, 5000);
      document.getElementById('pbSrcScoutResult').innerHTML += translate('Waiting for rally point to clear')+'...';
      return;
    }
    
    var coords = list[count].split("_");
    
    if(coords[0] == 'undefined' || coords[1] == 'undefined')
    {
      document.getElementById('pbSrcScoutResult').innerHTML += '<SPAN class=boldRed>'+translate("ERROR")+': '+translate("Invalid coords")+'</span>';
      t.clickedStartScout();
      return;
    }
    
    document.getElementById('pbSrcScoutResult').innerHTML += translate('Sending scouts to ')+coords[0]+','+coords[1]+'...';
    document.getElementById('pbsrcScoutCheck_'+coords[0]+'_'+coords[1]).checked = false;

    t.sendScout(coords[0], coords[1], city, count, function(c){t.doScoutCount(list, city, total, c)});
  },
  
  sendScout : function(x, y, city, count, notify)
  {
    var t = Tabs.Search;
    count = parseInt(count);
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid = city.id;
    params.kid = 0;
    params.type = 3;
    params.xcoord = x;
    params.ycoord = y;
    params.u3 = Options.srcScoutAmt;
    
    var _ajaxCall = function()
    {
      var profiler = new CM.Profiler("ResponseTime", "march.php");
      new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
         
        onSuccess: function (rslt) 
        {
          profiler.stop();
          rslt = eval("(" + rslt.responseText + ")");
          if (rslt.ok) 
          {
            addOutgoingMarch(params, rslt);
            
            CheckUpdateSeed(rslt);
            
            document.getElementById('pbSrcScoutResult').innerHTML += translate('Sent!')+'<BR>';
            
            if (notify)
             setTimeout(function(){ notify(count + 1); }, 1000);
          } 
          else 
          {
            if (rslt.user_action) 
            {
              var user_action = 
              {
                marchWarning: function() 
                {
                  logit('Captcha: [scouting] captcha warning');
                  actionLog('Captcha: [scouting] captcha warning');
                  if (notify)
                    setTimeout(function(){ notify(count); }, 1000);
                },
                marchCaptcha: function() 
                {
                  actionLog('Captcha: [scouting] triggered captcha');
                  logit('Captcha: [scouting] triggered captcha');
                  startCaptcha();
                },
                backOffWaitTime: function() 
                {
                  logit('Captcha: [scouting] back off time - ' + rslt.wait_time);
                  actionLog('Captcha: [scouting] back off time - ' + rslt.wait_time);
                  params.tt = rslt.tt;
                  setTimeout(_ajaxCall, rslt.wait_time * 1000)
                }
              };
              user_action[rslt.user_action].call();
            }
            else
            {
              if(document.getElementById('pbskip').checked) 
              {
                jQuery('#pbSrcScoutResult').html(translate('Failed! Moving on') + '....<BR>');
                
                if (notify)
                {
                  setTimeout(function(){ notify(count + 1); }, 1000);
                }
              } 
              else 
              {
                jQuery('#pbSrcScoutResult').html(translate('Failed! Retrying') + '....<BR>');
                
                if (notify)
                {
                  setTimeout(function(){ notify(count); }, 1000);
                }
              }
            }
          }
        },
        
        onFailure: function () 
        {
          profiler.stop();  
        }
      });
    };
    _ajaxCall();
  },
  
  getRallypoint: function(cityId)
  {
      var t = Tabs.Search;
    cityId = 'city'+cityId;
      for (o in Seed.buildings[cityId]){
    var buildingType = parseInt(Seed.buildings[cityId][o][0]);
    var buildingLevel = parseInt(Seed.buildings[cityId][o][1]);
    if (buildingType == 12){
      return parseInt(buildingLevel);
      break;
    }
     }
    return 0;
  },
  
  clickedStartScout : function()
  {
    var t = Tabs.Search;
    if(t.scouting == false){
      t.scouting = true;
      var ScoutList = [];
      for(k=0; k<document.getElementsByName('pbsrcScoutCheck').length; k++){
        if(document.getElementsByName('pbsrcScoutCheck')[k].checked){
          ScoutList.push(document.getElementsByName('pbsrcScoutCheck')[k].value);
        }
      }
      t.doScout(ScoutList, t.scoutcity);
      document.getElementById('pbSrcStartScout').className = 'button20 pbButCancel';
      document.getElementById('pbSrcStartScout').innerHTML = '<SPAN>'+translate("Stop")+'</span>';
    } else {
      t.scouting = false;
      document.getElementById('pbSrcStartScout').className = 'button20 ptButton20';
      document.getElementById('pbSrcStartScout').innerHTML = '<SPAN>'+translate("Start Scout")+'</span>';
    }
  },
    
  
/** mapdata.userInfo:
(object) u4127810 = [object Object]
    (string) n = George2gh02    (name)
    (string) t = 1              (title code)
    (string) m = 55             (might)
    (string) s = M              (sex)
    (string) w = 2              (mode: 1=normal, 2=begprotect, 3=truce, 4=vacation )
    (string) a = 0              (alliance)
    (string) i = 1              (avatar code)
*****/
  mapCallback : function (uList){
    var t = Tabs.Search;

    var rslt = t.SearchList;
  map = rslt.data;
    var Dip = Seed.allianceDiplomacies; 
    var userInfo = rslt.userInfo;
    var alliance = rslt.allianceNames;
  
    for (k in map){
      if (t.opt.searchType==0 && map[k].tileType==51 && !map[k].tileCityId ) {  // if barb
        type = 0;
      } else if (t.opt.searchType==1 && map[k].tileType>=10 &&  map[k].tileType<=50) { // if wild
        if (map[k].tileType == 10)
          type = 1;
        else if (map[k].tileType == 11)
          type = 2;
        else
          type = (map[k].tileType/10) + 1;
      } else if (t.opt.searchType==1 && map[k].tileType==54) {
        type = 8;
      } else if (t.opt.searchType==2 && map[k].tileCityId>=0 && map[k].tileType>50 && map[k].cityName) {
        type = 7;
      } else
        continue;
        
      var dist = distance (t.opt.startX, t.opt.startY, map[k].xCoord, map[k].yCoord);
      if ((t.opt.searchShape=='circle' && dist <= t.opt.maxDistance)
      ||  (t.opt.searchShape=='square' && map[k].xCoord>=t.firstX && map[k].xCoord<=t.lastX && map[k].yCoord>=t.firstY && map[k].yCoord<=t.lastY)){
        if (t.opt.searchType==2) {    // if city search
          var isMisted = map[k].tileUserId == 0 || false;   
          var uu = 'u'+map[k].tileUserId;
          var aD = '';
          var nameU = '';
          var mightU = '';
          var aU = '';
          if (!isMisted && userInfo[uu]) {
            nameU = userInfo[uu].n;   // can error, must check if (userInfo[uu])
            mightU = userInfo[uu].m;
            if (alliance['a'+userInfo[uu].a])
              aU = alliance['a'+userInfo[uu].a];
            else
              aU = '----';
            aD = '';
            if (Dip.friendly && Dip.friendly['a'+userInfo[uu].a]) aD = 'f';
            if (Dip.hostile && Dip.hostile['a'+userInfo[uu].a]) aD = 'h';
          if (Dip.allianceId && Dip.allianceId==userInfo[uu].a) aD = 'a';
          if (getDiplomacy(userInfo[uu].a) == 'neutral') aD = 'n';
          if (!userInfo[uu].a || userInfo[uu].a==0) aD = 'u';
          
          }
// TODO: save memory, remove city name ?        
          t.mapDat.push ([map[k].xCoord, map[k].yCoord, dist, type, map[k].tileLevel, isMisted, map[k].tileCityId, map[k].tileUserId, map[k].cityName, nameU, mightU, aU, aD, uList.data[map[k].tileUserId]?1:0]);
        } else {
          isOwned = map[k].tileUserId>0 || map[k].misted;
          t.mapDat.push ([map[k].xCoord, map[k].yCoord, dist, type, map[k].tileLevel, isOwned, (map[k].tileUserId>0? map[k].tileUserId : 0), uList.data[map[k].tileUserId]?1:0]);
        }
        ++t.tilesFound;
      }
    }
    
    t.tilesSearched += (15*15);
    document.getElementById('pastatSearched').innerHTML = translate('Searched: ')+ t.tilesSearched;
    t.dispMapTable();

    t.curX += 15;
    if (t.curX > t.lastX){
      t.curX = t.firstX;
      t.curY += 15;
      if (t.curY > t.lastY){
        t.stopSearch (translate('Done!'));
        return;
      }
    }
    var x = t.MapAjax.normalize(t.curX);
    var y = t.MapAjax.normalize(t.curY);
    document.getElementById ('pastatStatus').innerHTML = 'Searching at '+ x +','+ y;
    setTimeout (function(){t.MapAjax.request (x, y, 15, t.eventgetplayeronline)}, MAP_DELAY);
  },
  
  eventgetplayeronline : function (left, top, width, rslt)
  {
    var t = Tabs.Search;
    
    if (!t.searchRunning)
      return;
    
    if (!rslt.ok)
    {
      t.stopSearch (translate('ERROR')+': '+ rslt.errorMsg);
      return;
    }
  
    map = rslt.data;
    t.SearchList = rslt;
    var uList = [];

    for(k in map)
    {
      if(map[k].tileUserId != null)
        uList.push(map[k].tileUserId);
    }
    
    t.fetchPlayerStatus (uList, function(r){ t.mapCallback(r)});
  },

  clickedScout : function (x, y){
    unsafeWindow.modal_attack (3, x, y);
    CwaitForElement ('modal_attack', 5000, function (){document.getElementById('modalBox1').style.zIndex='112000'});
  },
    
  clickedLookup : function (pid){
    var t = Tabs.Search;
    var pop = new pbPopup ('pbsrclookup', 0,0, 500,500, true);
    if (t.popFirst){
      pop.centerMe (mainPop.getMainDiv());  
      t.popFirst = false;
    }
    pop.getTopDiv().innerHTML = '<CENTER><B>'+translate("Player Lookup")+'</b></center>';
    pop.getMainDiv().innerHTML = '<DIV class=pbStat>'+translate("Leaderboard information")+'</div><SPAN id=pblupLB>'+translate("Looking up leaderboard")+'...</span>\
      <BR><DIV class=pbStat>'+translate("Alliance Lookup")+'</div><SPAN id=pblupAI>'+translate("Looking up alliance info")+'...</span>';
    pop.show (true);
    t.fetchLeaderboard (pid, function (r){t.gotPlayerLeaderboard(r, document.getElementById('pblupLB'))});
    t.fetchPlayerInfo (pid, function (r){t.gotPlayerInfo(r, document.getElementById('pblupAI'))});
  },

  ExportToRaid : function (X,Y){
    var t = Tabs.Search;
    var cityId =t.selectedCity['id'];
    var pop = new pbPopup ('pbExportRaid', 0,0, 800,300, true);
    if (t.popFirst){
      pop.centerMe (mainPop.getMainDiv());  
      t.popFirst = false;
    }
    pop.getTopDiv().innerHTML = '<CENTER><B>'+translate("Export to Raid")+'</b></center>';
    
    var m = '<TABLE id=pbRaidAdd width=100% height=0% class=pbTab><TR align="center">';
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_50.jpg?6545"></td>';
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt1']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt2']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt3']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt4']) +'</td></tr>'
    m += '<TR><TD><INPUT id=Unit1 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit2 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit3 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit4 type=text size=6 maxlength=6 value="0"></td></tr>';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_50.jpg?6545"></td>';
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt5']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt6']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt7']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt8']) +'</td></tr>'
    m += '<TR><TD><INPUT id=Unit5 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit6 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit7 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit8 type=text size=6 maxlength=6 value="0"></td></tr>';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_50.jpg?6545"></td>';
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt9']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt10']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt11']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt12']) +'</td></tr>'
    m += '<TR><TD><INPUT id=Unit9 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit10 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit11 type=text size=6 maxlength=6 value="0"></td>';
    m += '<TD><INPUT id=Unit12 type=text size=6 maxlength=6 value="0"></td></tr></table>';
    
    m += '<BR><CENTER>' +strButton20(translate('Help'), 'id=pbHelp')+'<SELECT id=RaidKnights type=list></select></center>';
    m+= '<BR><CENTER>'+ strButton20(translate('Raid and save'), 'id=pbRaidSave') +'</center>';
          
    pop.getMainDiv().innerHTML = m;
    
    t.getKnights();
    
    document.getElementById ('pbHelp').addEventListener ('click', t.helpPop, false);
    document.getElementById ('pbRaidSave').addEventListener ('click', function(){
      var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
                
      params.pf = 0;
        params.ctrl = 'BotManager';
      params.action = 'saveMarch';
      params.settings = {};
      params.settings.cityId = cityId;
      params.queue = {0:{botMarches:{botMarchStatus:1,botState:1},cityMarches:{}}};     
      params.queue[0].cityMarches.knightId = parseInt(document.getElementById ('RaidKnights').value);
      params.queue[0].cityMarches.toXCoord = X;
      params.queue[0].cityMarches.toYCoord = Y;
      params.queue[0].cityMarches.unit0Count = 0;
      params.queue[0].cityMarches.unit1Count = parseInt(document.getElementById ('Unit1').value);
      params.queue[0].cityMarches.unit2Count = parseInt(document.getElementById ('Unit2').value);
      params.queue[0].cityMarches.unit3Count = parseInt(document.getElementById ('Unit3').value);
      params.queue[0].cityMarches.unit4Count = parseInt(document.getElementById ('Unit4').value);
      params.queue[0].cityMarches.unit5Count = parseInt(document.getElementById ('Unit5').value);
      params.queue[0].cityMarches.unit6Count = parseInt(document.getElementById ('Unit6').value);
      params.queue[0].cityMarches.unit7Count = parseInt(document.getElementById ('Unit7').value);
      params.queue[0].cityMarches.unit8Count = parseInt(document.getElementById ('Unit8').value);
      params.queue[0].cityMarches.unit9Count = parseInt(document.getElementById ('Unit9').value);
      params.queue[0].cityMarches.unit10Count = parseInt(document.getElementById ('Unit10').value);
      params.queue[0].cityMarches.unit11Count = parseInt(document.getElementById ('Unit11').value);
      params.queue[0].cityMarches.unit12Count = parseInt(document.getElementById ('Unit12').value);
      
       new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, {
            method: "post",
               parameters: params,
           loading: true,
           onSuccess: function(transport){
            var rslt = eval("(" + transport.responseText + ")");
                        if (rslt.ok) {
                            pop.show (false);
                unsafeWindow.cityinfo_army();
                            setTimeout(unsafeWindow.update_seed_ajax, 250);
             } else ('Error :' + rslt.msg);
             
           },
       });
      }, false);
    
    pop.show (true);
  },
  
  getKnights : function() 
  {
    var t = Tabs.Search;
    cityId = t.selectedCity['id'];
    var knt = getFreeKnight(cityId);
 
    document.getElementById('RaidKnights').options.length=0;
    var o = document.createElement("option");
    o.text = '--Choose a Knight--';
    o.value = 0;
    document.getElementById("RaidKnights").options.add(o);
    
    for (k in knt)
    {
      if (knt[k]["Name"] !=undefined)
      {
        var o = document.createElement("option");
        o.text = (knt[k]["Name"] + ' (' + knt[k]["Combat"] +')')
        o.value = knt[k]["ID"];
        document.getElementById("RaidKnights").options.add(o);
      }
    }
  },
  
  gotPlayerLeaderboard : function (rslt, span){
    var t = Tabs.Search;
    if (!rslt.ok){
      span.innerHTML = rslt.errorMsg;
      return;
    }
    if (rslt.totalResults == 0){
      span.innerHTML = '<B>'+translate("Leaderboard")+':</b> '+translate("Not found")+'! ('+translate("misted")+'?)<BR><BR>';
      return;
    }
    var p = rslt.results[0];
    var x;
    var name = '';
    if (p.playerSex == 'M')
      name = 'Lord ';
    else if (p.playerSex == 'F')
      name = 'Lady ';   
    name += p.displayName;      
    if ((x = officerId2String(p.officerType)) != '')  
      name += ' ('+ x + ')';  
    var aName = p.allianceName;
    if (!aName || aName=='')
      aName = 'none';
             
    var m = '<CENTER><SPAN class=boldRed>'+translate("NOTE: Leaderboard information is delayed up to 24 hours")+'</span></center><TABLE class=pbTabSome>';
    m += '<TR><TD class=pbDetLeft>'+translate("Player Name")+':</td><TD>'+ name +'</td></tr>\
      <TR><TD class=pbDetLeft>'+translate("Might")+':</td><TD>'+ p.might +' ('+translate("rank")+' #'+ p.rank +')</td></tr>\
      <TR><TD class=pbDetLeft>'+translate("Alliance")+':</td><TD>'+ aName +' ('+ getDiplomacy(p.allianceId) +')</td></tr>\
      <TR valign=top><TD class=pbDetLeft>'+translate("Cities")+':</td><TD><TABLE class=pbTabSome><TR style="font-weight:bold"><TD>'+translate("City Name")+'</td><TD>'+translate("Coords")+'</td><TD>'+translate("Level")+'</td><TD>'+translate("Status")+'</td><TD>'+translate("Created")+'</td></tr>';
      
    for (var i=0; i<p.cities.length; i++){
      var c = p.cities[i];
      var created = '';
      if (c.dateCreated && c.dateCreated.substr(0,2)=='20')
        created = c.dateCreated.substr(0,10);
      m += '<TR><TD>'+ c.cityName +'</td><TD>'+ coordLink(c.xCoord, c.yCoord) +'</td><TD align=center>'+ c.tileLevel +'</td>\
          <TD>'+ cityStatusString (c.cityStatus) +'</td><TD>'+ created +'</td></tr>';
    }    
    m += '</table></td></tr></table>';
    span.innerHTML = m;
  },

  gotPlayerInfo : function (rslt, span){
    var t = Tabs.Search;
    if (!rslt.ok){
      span.innerHTML = rslt.errorMsg;
      return;
    }
    var m = '<TABLE class=pbTabSome>';
    var p = rslt.userInfo[0];
    var pids = p.provinceIds.split (',');
    var prov = [];
    for (var i=0; i<pids.length; i++)
      prov.push(unsafeWindow.provincenames['p'+pids[i]]);
    m += '<TR><TD class=pbDetLeft>'+translate("Player Name")+':</td><TD>'+ p.genderAndName +'</td></tr>\
      <TR><TD class=pbDetLeft>'+translate("Might")+':</td><TD>'+ p.might +'</td></tr>\
      <TR><TD class=pbDetLeft>'+translate("Facebook profile")+':</td><TD><A target="_tab" href="http://www.facebook.com/profile.php?id='+ p.fbuid +'">'+translate("Click to open in new tab")+'</a></td></tr>\
      <TR><TD class=pbDetLeft>'+translate("Alliance")+':</td><TD>'+ p.allianceName +' ('+ getDiplomacy(p.allianceId) +')</td></tr>\
      <TR valign=top><TD class=pbDetLeft>'+translate("Provinces")+':</td><TD style="white-space:normal">'+ prov.join(', ') +'</td></tr>';
    span.innerHTML = m + '</table>';
  },
      
  fetchPlayerInfo : function (uid, notify){
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.uid = uid;
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getUserGeneralInfo.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) {
        notify (rslt);
      },
      onSuccess: function (rslt) {
        notify (rslt);
      },
    });
  },
  
  fetchLeaderboard : function (uid, notify) 
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.userId = uid;
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getUserLeaderboard.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) {
        notify (rslt);
      },
      onFailure: function (rslt) {
        notify (rslt);
      },
    });
  },
  
  fetchPlayerStatus : function (uidArray, notify)
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.checkArr = uidArray.join(',');
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getOnline.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) {
        notify (rslt);
      },
      onFailure: function (rslt) {
        notify ({errorMsg:'AJAX error'});
      },
    });
  },
  
};   // end Search tab




/******** Export to KOC Attack **********/  

var exportToKOCattack = {
  troops : {},  
  
  init : function (){
    var t = exportToKOCattack;
    for (var b=1; b<11; b++){
      t.troops['b'+ b] = [];
      for (var trp=0; trp<12; trp++){
        t.troops['b'+ b][trp] = 0;
      }
    }
    var s = GM_getValue ('atkTroops_'+ getServerId(), null);
    if (s != null){
      var trp = JSON2.parse(s);
      for (var b=1; b<11; b++){
        if (trp['b'+ b] && trp['b'+ b].length == 12)
          t.troops['b'+ b] = trp['b'+ b];
      }
    }
    window.addEventListener('unload', t.onUnload, false);
  },
  
  onUnload : function (){
    var t = exportToKOCattack;
    if (!ResetAll) GM_setValue ('atkTroops_'+ getServerId(),  JSON2.stringify(t.troops));
  },
  
  doExport : function (coordList, city){
    var t = exportToKOCattack;
    var popExp = null;
    var cList = coordList;
    var curLevel = 0;
    var city = city;
    var troopDef = [
      ['STroop', 1],
      ['Wagon', 9],
      ['Archers', 6],
      ['Cavalry', 7],
      ['Heavies', 8],
      ['Ballista', 10],
    ];
    
    if (popExp == null){
      popExp = new pbPopup ('pbsrcexp', 0,0, 625,600, true, function (){popExp.destroy(); popExp=null;});
      popExp.centerMe (mainPop.getMainDiv());  
    }
    var m = '<DIV class=pbStat>Export data to KOC Attack</div><BR><TABLE align=center cellpadding=0 cellspacing=0 class=pbTabPadNW>\
      <TR style="font-weight:bold; background-color:white"><TD>Target Type</td><TD style="padding:1px" align=center>#<BR>targets</td><TD width=15></td>';
    for (var i=0; i<troopDef.length; i++)
      m += '<TD>'+ troopDef[i][0] +'</td>';
    m += '</tr>';
    for (var b=1; b<11; b++){
      m += '<TR><TD>Barb level '+ b +'</td><TD align=right>'+ coordList['lvl'+b].length  +'&nbsp; &nbsp;</td><TD></td>';
      for (var td=0; td<troopDef.length; td++)
        m += '<TD><INPUT id=ptET_'+ b +'_'+ troopDef[td][1] +' type=text size=3 value="'+ t.troops['b'+ b][troopDef[td][1]-1] +'"></td>';
      m += '<TD width=90%><SPAN class=boldRed id=ptETerr_'+ b +'></span></tr>';
    }
    m += '</table>';
    var isKOCattack = !(document.getElementById('KOCAttackToggle') == null);
    
    //TODO: 'RESET VALUES' button ?
    
    if (isKOCattack){
      m += '<BR><CENTER>'+ strButton20('Bulk Add to KOC Attack', 'id=pbSrcDoBA') +'</center>';
    } else {
      m += 'KOC Attack not running, unable to export';
    }
    m += '<CENTER><DIV style="width:70%" id=pbSrcExpResult></DIV></center>';
    popExp.getMainDiv().innerHTML =  m;
    for (var b=1; b<11; b++)
      for (var td=0; td<troopDef.length; td++)
        document.getElementById('ptET_'+ b +'_'+ troopDef[td][1]).addEventListener ('change', validate, false);
    
    popExp.getTopDiv().innerHTML = '<CENTER><B>Power Bot Export</b></center>';
    if (isKOCattack)    
      document.getElementById ('pbSrcDoBA').addEventListener ('click', doBulkAdd, false);
    popExp.show(true);
         
    if (city != null){
      for (var i=0; i<Cities.numCities; i++)
        if (city.id == Cities.cities[i].id)
          break;
      if (i < Cities.numCities){
        setTimeout (function(){unsafeWindow.citysel_click(document.getElementById('citysel_'+ (i+1)));}, 0);
//logit ("SWITCH CITY: "+ (i+1));          
      }
    }
// TODO: WAIT FOR City select ?
    
  
    function validate (e){
      var x = e.target.id.substr(5).split('_');
      var b = x[0];
      var trp = x[1];
      document.getElementById('ptETerr_'+ b).innerHTML = '';
      var x = parseIntZero (e.target.value);
      if (isNaN(x) || x<0 || x>150000){
        e.target.style.backgroundColor = 'red';
        document.getElementById('ptETerr_'+ b).innerHTML = 'Invalid Entry';
        return;
      } else {
        e.target.style.backgroundColor = '';
        e.target.value = x;
        t.troops['b'+ b][trp-1] = x;
      }
      var tot = 0;
      for (var td=0; td<troopDef.length; td++)
        tot += parseIntZero(document.getElementById('ptET_'+ b +'_'+ [troopDef[td][1]]).value);
      if (tot<1 && cList['lvl'+ b].length>0 )
        document.getElementById('ptETerr_'+ b).innerHTML = 'No troops defined';
      if (tot>150000)
        document.getElementById('ptETerr_'+ b).innerHTML = 'Too many troops';
    }
      
    function doBulkAdd (){
      for (var b=1; b<11; b++){
        if (document.getElementById('ptETerr_'+ b).innerHTML != '')
          return;
        var tot = 0;
        for (var td=0; td<troopDef.length; td++)
          tot += t.troops['b'+b][troopDef[td][1]-1];
        if (tot<1 && cList['lvl'+ b].length>0){
          document.getElementById('ptETerr_'+ b).innerHTML = 'No troops defined';
          return;
        } else if (tot>150000) {
          document.getElementById('ptETerr_'+ b).innerHTML = 'Too many troops';
          return;
        }
      }    
      document.getElementById('pbSrcExpResult').innerHTML = '';
      doNextLevel ();
    }
    
    function endBulkAdd (msg){
      unsafeWindow.Modal.hideModalAll();
      curLevel = 0;
      showMe ();
      popExp.show(true);
      document.getElementById('pbSrcExpResult').innerHTML += msg;
    }
    
    function doNextLevel (){
      while ( curLevel<10 && cList['lvl'+ ++curLevel].length==0)
        ;
      if (curLevel>=10){
        endBulkAdd ('Done!<BR>');
        return;
      }
     e_attackDialog(false);
    }
        
    function e_attackDialog (tf){
      if (!tf){
       hideMe();
       popExp.show (false);
       unsafeWindow.Modal.hideModalAll();
       unsafeWindow.modal_attack(4,0,0);
       new CwaitForElement ('BulkAddAttackDiv', 1000, e_attackDialog );
      }
      var div = searchDOM (document.getElementById('BulkAddAttackDiv'), 'node.tagName=="DIV" && node.style.display=="none"', 10);
      if (div==null){
        endBulkAdd ('<SPAN class=boldRed>ERROR: Unexpected attack dialog format (1).</span>');
        return;  
      }
      var ta = searchDOM (div, 'node.tagName=="TEXTAREA"', 10);
      var but = searchDOM (div, 'node.tagName=="A"', 10);
      if (ta==null || but==null){
        endBulkAdd ('<SPAN class=boldRed>ERROR: Unexpected attack dialog format (2).</span>');
        return;  
      }
      for (var trp=1; trp<13; trp++){
        var inp = document.getElementById('modal_attack_unit_ipt' +trp);
        inp.value = t.troops['b'+curLevel][trp-1];
        if (t.troops['b'+curLevel][trp-1] > 0)
          inp.style.backgroundColor = 'yellow';
        else
          inp.style.backgroundColor = 'white';
      }
      div.style.display = 'block';
      document.getElementById('KOCAttackBulkAddForce').checked = true;
      if (DISABLE_BULKADD_LIST)
        ta.value = '';
      else {
        var m = '';
        var list = cList['lvl'+ (curLevel)];
        for (i=0; i<list.length; i++)
          m += list[i].x +','+ list[i].y +'\n';
        ta.value = m;
      }
      clickWin (unsafeWindow, but, 'click');   
      unsafeWindow.Modal.hideModal();
      document.getElementById('pbSrcExpResult').innerHTML += 'Added '+ list.length +' targets for '+ city.name +'<BR>';
      setTimeout (doNextLevel, 500);
    }    
  },
}


  function searchDOM (node, condition, maxLevel, doMult){
    var found = [];
    eval ('var compFunc = function (node) { return ('+ condition +') }');
    doOne(node, 1);
    if(!doMult){
      if (found.length==0)
        return null;
      return found[0];
    }
    return found;
    function doOne (node, curLevel){
      try {
        if (compFunc(node))
          found.push(node);
      } catch (e){
      }      
      if (!doMult && found.length>0)
        return;
      if (++curLevel<maxLevel && node.childNodes!=undefined)
        for (var c=0; c<node.childNodes.length; c++)
          doOne (node.childNodes[c], curLevel);
    }
  }



/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Sample
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.sample = {
  tabOrder : 300,                    // order to place tab in top bar
  tabDisabled : !ENABLE_SAMPLE_TAB, // if true, tab will not be added or initialized
  tabLabel : 'Click Me',            // label to show in main window tabs
  myDiv : null,
  timer : null,  
  
  init : function (div){    // called once, upon script startup
    var t = Tabs.sample;
    t.myDiv = div;
    var cityName = Cities.cities[0].name;
    div.innerHTML = '<CENTER><BR>This is a sample tab implementation<BR><BR>Showing food for '+ cityName +' : <SPAN id=pbSampleFood>0</span>\
        <BR><BR>(Food is updated every 5 seconds)</center>';
  },
  
  hide : function (){         // called whenever the main window is hidden, or another tab is selected
    var t = Tabs.sample;
    clearTimeout (t.timer);
  },
  
  show : function (){         // called whenever this tab is shown
    var t = Tabs.sample;
    var food = parseInt(Seed.resources['city'+ Cities.cities[0].id]['rec'+1][0] / 3600);
    document.getElementById('pbSampleFood').innerHTML = addCommas (food);
    clearTimeout (t.timer);
    t.timer = setTimeout (t.show, 5000);
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: debug
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.debug = 
{
  tabOrder : 950,                    // order to place tab in top bar
  tabDisabled : true, // if true, tab will not be added or initialized
  tabLabel : 'Debug',            // label to show in main window tabs
  myDiv : null,
  timer : null,
  
  init : function (div)
  {
    var t = Tabs.debug;
    t.myDiv = div;
    div.innerHTML = '<div id=pbMainTestDiv></div>';
  },
  
  hide : function ()
  {
    var t = Tabs.debug;
    clearTimeout (t.timer);
  },
  
  show : function ()
  {
    var t = Tabs.debug;
    
    var m = 'Debug Information';
    m += '<br>March delay <INPUT id=pbBaseRequest1 type=text size=3 maxlength=3 value="' + Options.baseRequest + '"/> seconds';
    m += '<br>Request delay <INPUT id=pbShortMarchDelay1 type=text size=3 maxlength=3 value="' + Options.shortMarchDelay + '"/> seconds';
    m += '<br>Captcha march delay <INPUT id=pbCaptchaDuration1 type=text size=3 maxlength=3 value="' + Options.captchaDuration + '"/> minutes';
    m += '<br>Captcha count <INPUT id=pbCaptchaCount1 type=text size=3 maxlength=3 value="' + Options.captchaCount + '"/>';
    m += '<br>';
    m += '<br>Sacrifice count <INPUT id=pbCaptchaCount1 type=text size=3 maxlength=3 value="' + Options.autoSacrificeCount + '"/>';
    m += '<br>';
    m += '<br>Throne read interval <INPUT id=throneReadInterval type=text size=3 maxlength=3 value="' + Options.throneReadInterval + '"/>';
    m += '<br>';
    m += '<br>Alliance ID : ' + Options.AllianceId ;
    m += '<br>Previous Alliance ID : ' + Options.PrevAllianceId ;
    m += '<br>Output Debug : &nbsp; </td><TD><INPUT id=autoDefendHideHC type=checkbox '+ (Options.outputDebug?'CHECKED ':'') +'/>';

    jQuery('#pbMainTestDiv').html(m);
    
    jQuery('#pbBaseRequest1').change( function()
    {
      logit("Debug: march request delay change");
      Options.baseRequest = parseInt(this.value);
      saveOptions();
    });
    
    jQuery('#outputDebug').change( function()
    {
      Options.outputDebug = this.checked;
      saveOptions();
    });
    
    jQuery('#throneReadInterval').change( function()
    {
      Options.throneReadInterval = parseInt(this.value);
      saveOptions();
    });
    
    jQuery('#pbShortMarchDelay1').change( function()
    {
      logit("Debug: short request delay change");
      Options.shortMarchDelay = parseInt(this.value);
      saveOptions();
    });

    jQuery('#pbCaptchaDuration1').change( function()
    {
      logit("Debug: captcha duration change");
      Options.captchaDuration = parseInt(this.value);
      saveOptions();
    });

    jQuery('#pbCaptchaCount1').change( function()
    {
      logit("Debug: captcha count change");
      Options.captchaCount = parseInt(this.value);
      saveOptions();
    });

    //clearTimeout (t.timer);
    //t.timer = setTimeout(t.show, 5 * 1000);
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: sacrifice
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.sacrifice = 
{
  tabOrder : 990,                    // order to place tab in top bar
  tabDisabled : false, // if true, tab will not be added or initialized
  tabLabel : 'Sacrifice',            // label to show in main window tabs
  myDiv : null,
  timer : null,
  
  init : function (div)
  {
    var t = Tabs.sacrifice;
    t.myDiv = div;
    div.innerHTML = '<div id=pbSacrificeDiv></div>';
  },
  
  hide : function ()
  {
    var t = Tabs.sacrifice;
    clearInterval (t.timer);
  },
  
  show : function ()
  {
    var t = Tabs.sacrifice;
    var selbut=0;
    var disableList = [true, true, true, true, true, true, true, true];

    for(i=0; i < Cities.numCities; i++) 
    {
      if(Seed.cityData.city[Cities.cities[i].id].isPrestigeCity)
      {
        if(Seed.cityData.city[Cities.cities[i].id].prestigeInfo.prestigeType == 2)
          disableList[i] = false;
      }
    }
    
    var m = '';
    m += '<table>';
    m += '<tr>';
    m += '<td colspan=3><div id=sacrificeCity></div></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Troop Type<select id=troopType></select></td>';
    m += '<td><INPUT id=sacrificeTroopCount type=text size=5 maxlength=5 value=0 /></td>';
    m += '<td><div id=sacrificeAvailableCount></div></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td colspan=3 style="text-align:center;"><a class="button20" id="sacrificeTroops"><span>Sacrifice</span></a></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td colspan=3><div id=sacrificeInfo></div></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td colspan=3><div id=sacrificeStatus></div></td>';
    m += '</tr>';
    m += '</table>';

    jQuery('#pbSacrificeDiv').html(m);
    jQuery('#sacrificeTroops').click(function()
    {
      var troopCount = parseIntWithDefault(jQuery('#sacrificeTroopCount').val());
      var troopType = jQuery('#troopType').val();
      var cityId = t.cityPicker.city.id;

      logit("Sacrifice: going to try and sacrifice now");

      jQuery('#sacrificeStatus').html("Sacrificing...");

      Tabs.tower.doSacrifice(cityId, troopType, troopCount, t.ShowSacrifice);
    });

 		t.cityPicker = new CdispCityPicker ('popcityselect', document.getElementById('sacrificeCity'), true, t.SacrificeCityChange, selbut, disableList);
    
    clearInterval (t.timer);
    t.timer = setInterval(t.ShowSacrifice, 5 * 1000);
  },
  
  SacrificeCityChange : function()
  {
    var t = Tabs.sacrifice;
    var options = "";

    options += "<option value='0'>...</option>";

    i = 1;
    for (var unit in unsafeWindow.unitcost)
    {
      if(Seed.units["city" + t.cityPicker.city.id]["unt"+i] > 0)
      {
        options += "<option value='" + i + "'>" + unsafeWindow.unitcost[unit][0] + "</option>";
      }
      i++;
    }

    jQuery('#troopType').html(options);
    jQuery('#troopType').change(function()
    {
      if(this.value == 0)
      {
        jQuery('#selectedValue').html("Need to select troop type!");
      }
      else
      {
        jQuery('#selectedValue').html(this.value);
      }
    });

    // cancelSacrificing.php
    // &cid=15724&type=6&quant=5000&start=1359672494&eta=1359672910

    t.ShowSacrifice();
  },

  ShowSacrifice : function(messageText)
  {
    var t = Tabs.sacrifice;
    var now = unixTime();
    var m = '';
    var cityId = t.cityPicker.city.id;

    m += '<table>';
    m += '<caption>Current Sacrificies</caption>';
    m += '<tr>';
    m += '<td>Type</td><td>Number of Troops</td><td>Remaining Time</td><td>&nbsp;</td>';
    m += '</tr>';

    if(messageText != undefined)
    {
      jQuery('#sacrificeStatus').html(messageText);
    }

    for (i = 0 ; i < Seed.queue_sacr["city" +cityId].length ; i++)
    {
      m += '<tr>';

      var sacrifice = Seed.queue_sacr["city" + cityId][i];

      var remainingTime = sacrifice.eta - now;
      m += '<td>' + unsafeWindow.unitcost["unt" + sacrifice.unitType][0] + '</td>';
      m += '<td>' + sacrifice.quantity + '</td>';
      m += '<td>' + timestr(remainingTime) + '</td>';
      m += '<td><a class="button20" id="sacrificeCancel_' + i + '"><span>Cancel</span></a></td>';
      m += '</tr>';
    }

    m += '</table>';
    
    jQuery('#sacrificeInfo').html(m);

    jQuery('[id^=sacrificeCancel]').click(function ()
    {
      var sacrificeId = this.id.substr(16);
      var sacrificeInfo = Seed.queue_sacr["city" + cityId][sacrificeId];

      jQuery('#sacrificeStatus').html("Cancelling sacrifice...");

      Tabs.tower.doCancelSacrifice(sacrificeInfo, t.ShowSacrifice);
    });
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Range
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Range = 
{
  tabOrder : 900,                 // order to place tab in top bar
  tabDisabled : false,            // if true, tab will not be added or initialized
  tabLabel : 'Range',             // label to show in main window tabs
  myDiv : null,
  rangeLookupTimer : null,  
  nameLookupTimer : null,
  blankName: [],
  rangeUpdates: [],
  myStats: null,
  hideBelow: 0,
  nameMatch: "",
  showUpdateTime : false,
  updateRequired : false,
  updateInterval : null,
  rangeUpdateTimer : {},
  baseStats : {},
  assumeDefenderSacrifice : false,
  assumeAttackerSacrifice : false,
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init : function (div)
  {          // called once, upon script startup
    var t = Tabs.Range;
    t.myDiv = div;
    var cityName = Cities.cities[0].name;
    var m = "";
    
    m += '<div align=left>';
    m += '<table class=pbTab>';
    m += '<tr><td><INPUT id=pbRangeUpdateEnable type=checkbox '+ (Options.rangeUpdateEnable ? 'CHECKED ' : '') +'/></td><td>&nbsp;' + translate("Enable Range Updates") + '</td></tr>';
    m += '</table>';
    m += '</div>';
    m += '<div align=center>';
    m += '<table class=pbTab><tr>';
    m += '<td><select id="rangeAlliances"></select></td>';
    m += '<td><a class="button20" id=addAllianceMembers><span>Monitor Alliance</span></a></td>';
    m += '<td><a class="button20" id=deleteAllianceMembers><span>Delete Alliance</span></a></td>';
    m += '<td><a class="button20" id=addAllAlliances><span>Monitor All Alliances</span></a></td>';
    m += '</tr></table>';
    m += '<div align=left><table class=pbTab padding=10px><tr>';
    m += '<td><a class="button20" id=clearFullList><span>Clear All</span></a>';
    // m += '<td><a class="button20" id=sortFullList><span>Sort List</span></a></td>';
    m += '<a class="button20" id=resetUpdateTimes><span>Reset Update Times</span></a></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>';
    m += '<a class="button20" id=loadRangeValues><span>Load Range Values from Web</span></a><input id=pbNetRangeUrl size="50" type="text" value="' + Options.rangeUpdateUrl + '"/>';
    m += '</td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>';
    m += '<a class="button20" id=exportRangeValues><span>Export Range Values for Web</span></a>';
    m += '</td>';
    m += '</tr>';
    m += '<tr>';
    m += '<TD colspan>Throne preset to compare against<SELECT id=rangeThronePreset type=list></select></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<TD colspan>Assume you sacrifice <INPUT id=pbAssumeDefenderSacrifice type=checkbox ' +  (t.assumeDefenderSacrifice ? 'CHECKED ' : ' ') + '/></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<TD colspan>Assume they sacrifice <INPUT id=pbAssumeAttackerSacrifice type=checkbox ' +  (t.assumeAttackerSacrifice ? 'CHECKED ' : ' ') + '/></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Quick Monitor UserId: <input id=rtUserId type="text"/><a class="button20" id=quickMonId><span>Monitor Now</span></a></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Filter for name: <input id=rtNameMatch type="text"/></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Hide Range Below: <input id=rtHideBelow type="text" name="range" /></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Update Range Interval: <select id=updateRangeInterval>';
    m += '<option value="3">3</option>';
    m += '<option value="5">5</option>';
    m += '<option value="10">10</option>';
    m += '<option value="20">20</option>';
    m += '<option value="30">30</option>';
    m += '</select> seconds</td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td><INPUT id=enableUpdateIntervalChange type=checkbox\>Enable change of update intervals</td>';
    m += '</tr></table></div>';
    m += '<div id= trStatsTabDiv2 style="margin-top:5px; margin-bottom:5px; margin-left: 5px; width:100%; height:600px; overflow : auto; ">';
    m += '<div id=rangeTable></div>';
    m += '</div>';
    m += '<div class=pbStat>'+translate("Status")+'</div>';
    m += '<div id="range_pop-up"></div><div id=rtStatus> </div><div>Showing <span id=rangeRecordsShowing></span> players</div>';
    m += '</div></div>';
     
    jQuery(div).html(m);
    
    for (i = 1 ; i <= Seed.throne.slotNum ; i++)
    {
      jQuery("#rangeThronePreset").append(
        jQuery('<option></option>').val(i).html(i)
      );
    }
    
    if(Options.throneAttackSlotEnable)
    {
      t.compareSlot = Options.throneAttackSlot;
    }
    else
    {
      t.compareSlot = Seed.throne.activeSlot;
    }
    
    jQuery('#quickMonId').click(function()
    {
      if(jQuery('#rtUserId').val() != "")
      {
        var data = {};
        data.user = {};
        data.user.id = parseIntWithDefault(jQuery('#rtUserId').val(), 0);
        
        t.quickMonitorUser(data);
      }
    });
    
    jQuery('#pbRangeUpdateEnable').click(function()
    {
      Options.rangeUpdateEnable = this.checked;
      saveOptions();
    });
    
    jQuery('#pbAssumeDefenderSacrifice').click(function()
    {
      t.assumeDefenderSacrifice = this.checked;
      t._updateTable();
    });
    
    jQuery('#pbAssumeAttackerSacrifice').click(function()
    {
      t.assumeAttackerSacrifice = this.checked;
      t._updateTable();
    });
    
    jQuery("#rangeThronePreset").val(t.compareSlot);
    
    jQuery('#updateRangeInterval').val(Options.updateRangeInterval);
    
    jQuery('#enableUpdateIntervalChange').change(function()
    {
      t.showUpdateTime = this.checked;
      t._updateTable();
    });
    
    jQuery('#updateRangeInterval').change(function()
    {
      Options.updateRangeInterval = jQuery('#updateRangeInterval').val();
      saveOptions();
      clearInterval(t.updateInterval);
      t.updateInterval = setInterval(t.updateRanges, Options.updateRangeInterval * 1000);
      
    });
    
    jQuery("#rangeThronePreset").change(function()
    {
      t.compareSlot = this.value;
      t.myStats = t.myThroneStats(t.compareSlot);
      t._updateTable();
    });

    //jQuery('body').append('<div id="range_pop-up"></div>');
    t.myStats = t.myThroneStats(t.compareSlot);
    
    t.fetchAllianceList(1, t.eventGotOtherAlliancePage);
    t.fetchAllianceList(2, t.eventGotOtherAlliancePage);
    
    jQuery('#addAllianceMembers').click(function()
    {
      var allianceId = jQuery('#rangeAlliances').val();

      t.fetchAllianceMemberList (allianceId, null, t.eventGotMemberList);
    });

    jQuery('#addAllAlliances').click(function()
    {
      jQuery("#rangeAlliances option").each(function()
      {
        t.fetchAllianceMemberList (jQuery(this).val(), null, t.eventGotMemberList);
        // add $(this).val() to your list
      });
    });

    jQuery('#rtHideBelow').bind("keyup change", function(event) 
    { 
      setBusy(true);
      logit("Range: [#" + event.target.id + "] event - " + event.type);
      switch(event.type)
      {
        case "keyup":
          this.value = this.value.replace(/[^0-9\.]/g,'');
          t.hideBelow = parseIntWithDefault(this.value, t.hideBelow);
          t._updateTable();
          break;
      }
      
      setBusy(false);
    });

    jQuery('#rtNameMatch').bind("change", function(event) 
    { 
      setBusy(true);
      logit("Range: [#" + event.target.id + "] event - " + event.type);
      switch(event.type)
      {
        case "change":
          if(this.value != t.nameMatch)
          {
            t.nameMatch = this.value
            t._updateTable();
          }
          break;
      }

      setBusy(false);
    });

    jQuery('#resetUpdateTimes').click(function()
    {
      setBusy(true);

      jQuery.each(Options.attackersRange, function(index, range)
      {
        range.updatePeriod = 0;
        range.periodUpdated = false;
      });
      
      t.checkData();
      t._updateTable();
      
      setBusy(false);
    });
    
    jQuery('#loadRangeValues').click(function()
    {
      setBusy(true);

      var url = jQuery('#pbNetRangeUrl').val();
      if(!url)
      {
        alert("You need to enter a url!");
      }
      else
      {
        Options.rangeUpdateUrl = url;
        saveOptions();
        setTimeout(t.loadFromNet(url), 100);
      }
    });

    jQuery('#exportRangeValues').click(function()
    {
      setBusy(true);

      var exportRangePopup = null;
      exportRangePopup = new pbPopup('pbRangeInfoPopup', 0, 0, 600, 500, true, function() {clearTimeout (1000);});
      var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto">';
      m += '<textarea rows=30 cols=100 id=rangeInfo></textarea>';
      m += '</div>';       
      exportRangePopup.getTopDiv().innerHTML = '<td><b>Export Range Information</b></td>';
      exportRangePopup.getMainDiv().innerHTML = m;
      exportRangePopup.show(true) ;
      setTimeout(function()
      {
        jQuery('#rangeInfo').text(JSON2.stringify(Options.attackersRange, null, 2));
        setBusy(false);
      }, 400);
    });
    
    jQuery('#deleteAllianceMembers').click(function()
    {
      var allianceId = jQuery('#rangeAlliances').val();

      t.fetchAllianceMemberList (allianceId, null, t.eventDeleteMemberList);
    });

    jQuery('#clearFullList').click(function()
    {
      if(confirm('Delete all the stored range data?'))
      {
        Options.attackersRange = {};
        t.blankName = [];
        t.rangeUpdates = [];
        t._updateTable();
      }
    });
    
    t.checkData();

    setInterval(t.updateNames, 20 * 1000);
    t.updateInterval = setInterval(t.updateRanges, Options.updateRangeInterval * 1000);
    setInterval(t.updateTime, 10 * 1000);
    setInterval(t.checkData, 60 * 1000);
    
    t._updateTable();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  loadFromNet : function(url)
  {
    var t = Tabs.Range;
    
    getJSONfromURL(url, t.loadRangeUpdates) 
    setBusy(false);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  importRange : function(playerId, rangeStats)
  {
    var playerStats = Options.attackersRange[playerId];
    var updateRequired = false;
    var now = unixTime();

    prevSiegeRange = parseIntWithDefault(playerStats.siegeRange,0) + parseIntWithDefault(playerStats.siegeRangeDebuff,0);
    newSiegeRange = rangeStats.siegeRange + rangeStats.siegeRangeDebuff;
    prevRangedRange = parseIntWithDefault(playerStats.rangedRange,0) + parseIntWithDefault(playerStats.rangedRangeDebuff,0);
    newRangedRange = rangeStats.rangedRange + rangeStats.rangedRangeDebuff;
    prevRange = parseIntWithDefault(playerStats.range,0) + parseIntWithDefault(playerStats.rangeDebuff,0);
    newRange = rangeStats.range + rangeStats.rangeDebuff;
    
    if(playerStats) 
    {
      if(prevRangedRange < newRangedRange) 
      {
        playerStats.rangedRange = rangeStats.rangedRange;
        playerStats.rangedRangeDebuff = rangeStats.rangedRangeDebuff;
        playerStats.lastChanged = now;
      }

      if(prevRange < newRange) 
      {
        playerStats.range = rangeStats.range;
        playerStats.rangeDebuff = rangeStats.rangeDebuff;
        playerStats.lastChanged = now;
      }

      if(prevSiegeRange < newSiegeRange) 
      {
        playerStats.siegeRange = rangeStats.siegeRange;
        playerStats.siegeRangeDebuff = rangeStats.siegeRangeDebuff;
        playerStats.lastChanged = now;
      }

      playerStats.lastChecked = now;

      if(parseIntWithDefault(playerStats.fletch,0) == 0) 
      {
        playerStats.fletch = 12;
      }
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  loadRangeUpdates : function(resultValue)
  {
    var t = Tabs.Range;
    var count = 0;
    
    logit("Range Test: - " + JSON2.stringify(resultValue, null, 2));
    
    // TODO for now we take the quick option and overwrite the data already stored
    Options.attackersRange = resultValue;
    t._updateTable();
    
    // for(player in resultValue)
    // {
      // if(!Options.attackersRange[player])
      // {
        // Options.attackersRange[player] = {};
      // }
      
      // t.importRange(player, resultValue[player]);
      
      // count += 1;
    // }
    
    saveOptions();
  },
  
  debugOut : function(player)
  {
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkRanges: function(myStats, attackerStats)
  {
    var t = Tabs.Range;
    
    attackerStats.defCatRange = troopRange(myStats, attackerStats, 12, t.assumeDefenderSacrifice);
    attackerStats.defBallRange = troopRange(myStats, attackerStats, 10, t.assumeDefenderSacrifice);
    attackerStats.defArcherRange = troopRange(myStats, attackerStats, 6, t.assumeDefenderSacrifice);
    attackerStats.attCatRange = troopRange(attackerStats, myStats, 12, t.assumeAttackerSacrifice);
    attackerStats.attBallRange = troopRange(attackerStats, myStats, 10, t.assumeAttackerSacrifice);
    attackerStats.attArcherRange = troopRange(attackerStats, myStats, 6, t.assumeAttackerSacrifice);

    var result = 0;
    
    if(attackerStats.attArcherRange > attackerStats.defCatRange)
    {
      result = 2;
    }
    else if(attackerStats.attCatRange > attackerStats.defCatRange)
    {
      result = 1;
    }
    else if(attackerStats.defArcherRange > attackerStats.attCatRange)
    {
      result = 10;
    }
    
    return result;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  myThroneStats: function (activeSlot) 
  {
    var t = Tabs.Range;
    var activeSlotItems = Seed.throne.slotEquip[activeSlot];
    var items = {};
    var stats;
   
    var slotNumber;
    
    for(slotNumber in activeSlotItems)
    {
      if(activeSlotItems.hasOwnProperty(slotNumber)) {
        var item = unsafeWindow.kocThroneItems[activeSlotItems[slotNumber]];
        
        items[activeSlotItems[slotNumber]] = item;
      }
    }

    stats = getThroneStats(items); 

    rangeStats = getRangeStats(stats);

    rangeStats.fletch = Seed.tech.tch13;
    
    return rangeStats;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateTime: function()
  {
    var t = Tabs.Range;
    
    logit("Range: Updating last checked times");
    
    jQuery.each(Options.attackersRange, function(i, val) 
    {
      jQuery('#rtLastUpdate_' + i).html(t._lastUpdateDisplay(val.lastChecked));      
    });

    var status = "";
    status =  "Pending range update requests - " + t.rangeUpdates.length + "<br />";
    status += "Pending name updates - " + t.blankName.length;
    jQuery('#rtStatus').html(status);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkData: function() 
  {
    var t = Tabs.Range;
    var now = unixTime();
    
    logit("Range: checking data for required updates");
    
    jQuery.each(Options.attackersRange, function(i, val) 
    {
      if(val.name == undefined)
      {
        if(i != undefined && i != 0)
        {
          if(t.blankName.indexOf(i) == -1)
          {
            // we add names that we do not have detail for to the start of the list
            //logit("Range: no name for id - " + i);
            t.blankName.unshift(i);
          }
        }
      }

      if((now > (val.lastNameCheck + (72 * 60 * 60))))
      {
        if(i != undefined && i != 0)
        {
          if(t.blankName.indexOf(i) == -1)
          {
            //logit("Range: name update time for - " + JSON2.stringify(val,null,2));
            t.blankName.push(i);
          }
        }
      }

      var basicRange = parseIntWithDefault(val.range, 0) + parseIntWithDefault(val.rangeDebuff, 0);
      var updatePeriod = 0;

      if(basicRange < 50)
      {
        updatePeriod = 120;
      } 
      else if(basicRange < 100)
      {
        updatePeriod = 60;
      }
      else if(basicRange < 150)
      {
        updatePeriod = 48;
      }
      else if(basicRange < 300)
      {
        updatePeriod = 24;
      }
      else if(basicRange < 400)
      {
        updatePeriod = 12;
      }
      else if(basicRange < 450)
      {
        updatePeriod = 6;
      }
      else
      {
        updatePeriod = 3;
      }
      
      if(val.updatePeriod == undefined || val.updatePeriod == 0 || updatePeriod != val.updatePeriod)
      {
        if(!val.periodUpdated)
        {
          val.updatePeriod = updatePeriod;
          //saveOptions();
        }
      }

      if(val.lastChecked == undefined || val.lastChecked == 0 || (now > val.lastChecked + (val.updatePeriod * 60 * 60)))
      {
        if(val.lastChecked == undefined)
        {
          val.lastChecked = 0;
        }
        
        if(i != "undefined")
        {
          if(t.rangeUpdates.indexOf(i) == -1)
          {
            if(val.lastChecked == 0)
            {
              // items with no history go to start of list to do before items with history.
              t.rangeUpdates.unshift(i);
            }
            else
            {
              t.rangeUpdates.push(i);
            }
          }
        }
      }
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateRanges: function()
  {
    var t = Tabs.Range;
    var id;
    
    logit("Range: Update range");
    
    t.myStats = t.myThroneStats(t.compareSlot);
    
    if(Options.rangeUpdateEnable && t.rangeUpdates.length > 0)
    {
      id = t.rangeUpdates.shift();
      t.fetchPlayerThrone(id, t.updateRange);
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateRange: function(aid, items)
  {
    var t = Tabs.Range;
    var stats = {};
    var now = unixTime();
    var update = false;

    logit("Range: Updating range for - " + aid);
    
    if(!Options.attackersRange[aid]) 
    {
      Options.attackersRange[aid] = {};
      saveOptions();
    }

    if(!SessionOptions.attackersRange[aid]) 
    {
      SessionOptions.attackersRange[aid] = {};
      SessionOptions.attackersRange[aid].updated = now;
    }

    stats = getThroneStats(items);
    
    rangeStats = getRangeStats(stats);
    
    updatePlayerRange(aid, rangeStats, function()
    {
      logit("Range: updating row for - " + aid);
      t._updateRow(aid, Options.attackersRange[aid]);
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateNames: function()
  {
    var t = Tabs.Range;
    var id;
    
    logit("Range: update name check");
    
    if(t.blankName.length > 0)
    {
      id = t.blankName.shift();
      logit("Range: update name - " + id);
      t.fetchPlayerInfo(id, t.updateName);
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateName: function(rslt)
  {
    var t = Tabs.Range;
    var now = unixTime();

    logit("Range: update name received - " + JSON2.stringify(rslt,null,2));
    
    if(rslt.ok) 
    {
      var user = rslt.userInfo[0];
      
      var attacker = Options.attackersRange[user.userId];
      var  attackerIndex = t.blankName.indexOf(user.userId);
      
      if(attackerIndex >= 0)
      {
        t.blankName.splice(attackerIndex,1);
      }
      
      attacker.lastNameCheck = now;

      logit("Range: Checking name - " + user.name);
      
      if(attacker.name != user.name)
      {
        attacker.name = user.name;
        jQuery("#rtName_" + user.userId).text(attacker.name.substring(0, 10));
        logit("Range: Update name - " + attacker.name);
      }
      
      if(attacker.alliance != undefined && attacker.alliance != user.allianceName)
      {
        attacker.alliance = user.allianceName;
        jQuery("#rtAlliance_" + user.userId).text(attacker.alliance.substring(0, 10));
        logit("Range: Update alliance - " + attacker.alliance);
      }
      
      saveOptions();

    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  eventDeleteMemberList : function (rslt)
  {
    var t = Tabs.Range;
    var update = false;
    
    if (!rslt.ok)
    {
      jQuery('allListOut').text(rslt.errorMsg);
      return;
    }
    
    for (k in rslt.results)
    {
      if(Options.attackersRange[rslt.results[k].userId] != undefined)
      {
        delete Options.attackersRange[rslt.results[k].userId];
        
        update = true;
      }
    }

    if(update)
    {
      t._updateTable();
      t.checkData();
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  eventGotMemberList : function (rslt)
  {
    var t = Tabs.Range;
    var update = false;
    
    if (!rslt.ok)
    {
      jQuery('allListOut').text(rslt.errorMsg);
      return;
    }
    
    for (k in rslt.results)
    {
      if(Options.attackersRange[rslt.results[k].userId] == undefined)
      {
        Options.attackersRange[rslt.results[k].userId] = {};
        Options.attackersRange[rslt.results[k].userId].lastChecked = 0;
        
        update = true;
      }
    }

    if(update)
    {
      t._updateTable();
      t.checkData();
    }
  },    
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  eventGotOtherAlliancePage : function (rslt)
  {
    var t = Tabs.Range;

    if (!rslt.ok){
      logit("Range: Error getting alliance list");
      jQuery('allListOut').html(rslt.errorMsg);
      return;
    }

    for (var i = 0 ; i < rslt.otherAlliances.length ; i++) 
    {
      var alliance = rslt.otherAlliances[i];
      logit("Range: Add alliance - " + alliance.name + " [" + alliance.allianceId + "]");

      var result = jQuery('#rangeAlliances>option[value="' + alliance.allianceId + '"]');
      
      if(result.length == 0)
      {
        jQuery('#rangeAlliances').append('<option id="rtAllianceSel_"' + alliance.name + ' value="' + alliance.allianceId + '">' + alliance.name + '</option>');
      }
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  monitorUser: function(data)
  {
    var t = Tabs.Range;

    if(Options.attackersRange[data.user.id] == undefined)
    {
      Options.attackersRange[data.user.id] = {};
      Options.attackersRange[data.user.id].lastChecked = 0;
      Options.attackersRange[data.user.id].name = data.user.username;
      Options.attackersRange[data.user.id].alliance = data.alliance.name;
      
      t.updateRequired = true;
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  quickMonitorUser : function(data)
  {
    var t = Tabs.Range;

    if(Options.attackersRange[data.user.id] == undefined)
    {
      Options.attackersRange[data.user.id] = {};
      Options.attackersRange[data.user.id].lastChecked = 0;
      Options.attackersRange[data.user.id].name = data.user.username;
      Options.attackersRange[data.user.id].alliance = data.alliance.name;
    }
    
    // create a new popup for displaying the data
    var displayRangePopup = new pbPopup('pbDisplayRange' + data.user.id, 0, 0, 500, 800, true, function() {t.closeThronePopup(data.user.id);} );
    logit("Throne Monitor: " + data.user.id);
        
    var m = '';
    m += '<table>';
    m += '<tr><td><div id=presetButton' + data.user.id + ' style="display:block;"></div></td></tr>';
    m += '<tr><td><div style="display:block;width:100%;text-align:center;"><a class="button20" id=resetThroneStats' + data.user.id + '><span>Reset Highlighted Changes</span></a></div></td></tr>';
    m += '<tr><td><div style="display:block;width:100%;text-align:center;"><a class="button20" id=delayRefresh' + data.user.id + '><span>Delay KOC Refresh</span></a></div></td></tr>';
    m += '<tr><td><div style="display:block;width:100%;text-align:center;"><a class="button20" id=disableThronePresets' + data.user.id + '><span>'+ (SessionOptions.DisablePreset ? 'Enable' : 'Disable') + ' Throne Swithcing</span></a></div></td></tr>';
    m += '<tr><td><div style="display:block;width:100%;text-align:center;"><a class="button20" id=disableDefendSwitch' + data.user.id + '><span>'+ (SessionOptions.DisableDefendSwitch ? 'Enable' : 'Disable') + ' Defend state swithcing</span></a></div></td></tr>';
    m += '<tr><td><div id=qmShowStats>Troop Stats</div></td></tr>';
    m += '<tr><td><div style="display:block; overflow-y:auto" id=throneStatsUpdatePopup' + data.user.id + '></div></td></tr>';
    m += '</table>';
    
    displayRangePopup.getMainDiv().innerHTML = m;
    displayRangePopup.getTopDiv().innerHTML = '<TD id=qmUserName><CENTER><B>Throne Stats: ' + data.user.username + '</b></center></td>';
    displayRangePopup.autoHeight (true);  
    displayRangePopup.autoWidth (true);  

    displayRangePopup.show(true);

    widget = buildPresetWidget("statMon" + data.user.id);
    jQuery('#presetButton' + data.user.id).html(widget);

    t.fetchPlayerThrone(data.user.id, t.parseItemList, true);

    var moveDown = 20;
    var moveLeft = 20;

    jQuery('#qmShowStats').hover(function(e) 
    {
      logit("Range: we should be displaying popup");
      if(Options.attackersRange[data.user.id])
      {
        jQuery('div#range_pop-up').html(t._createPopup(data.user.id));
      }
      
      jQuery('div#range_pop-up').show()
        .css('top', e.pageY + moveDown)
        .css('left', e.pageX + moveLeft)
        .css('z-index', 999999)
        .appendTo('body');
    }, function() {
      jQuery('div#range_pop-up').hide();
    });

    jQuery('#qmUserName').mousemove(function(e) {
      jQuery('div#range_pop-up').css('top', e.pageY + moveDown).css('left', e.pageX + moveLeft);
    });
    
    jQuery('#disableThronePresets' + data.user.id).click(function() 
    {
      SessionOptions.DisablePreset = !SessionOptions.DisablePreset;
      jQuery('[id^=disableThronePresets]').html('<span>'+ (SessionOptions.DisablePreset ? 'Enable' : 'Disable') + ' Throne Swithcing</span>');
    });
    
    jQuery('#disableDefendSwitch' + data.user.id).click(function() 
    {
      SessionOptions.DisableDefendSwitch = !SessionOptions.DisableDefendSwitch;
      jQuery('[id^=disableDefendSwitch]').html('<span>'+ (SessionOptions.DisableDefendSwitch ? 'Enable' : 'Disable') + ' Defend state switching</span>');
    });
    
    jQuery('#resetThroneStats' + data.user.id).click(function()
    {
      t.resetThronePopupStats(data.user.id);
    });
    
    jQuery('#delayRefresh' + data.user.id).click(function()
    {
      RefreshEvery.delay(5 * 60);
    });
                

    t.rangeUpdateTimer[data.user.id] = setInterval(function()
    {
      t.fetchPlayerThrone(data.user.id, t.parseItemList, true);
    }, Options.throneReadInterval * 1000);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addZero : function (i)
  {
    if (i < 10) 
    {
      i = "0" + i;
    }
    
    return i;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  parseItemList : function(aid, items)
  {
    var t = Tabs.Range;
    var now = unixTime();

    if(!Options.attackersRange[aid]) 
    {
      Options.attackersRange[aid] = {};
    }

    if(!SessionOptions.attackersRange[aid]) 
    {
      SessionOptions.attackersRange[aid] = {};
      SessionOptions.attackersRange[aid].updated = now;
    }

    stats = getThroneStats(items);
    
    rangeStats = getRangeStats(stats);
    
    updatePlayerRange(aid, rangeStats);
    
    t.populateStatsPopup(aid, stats);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  resetThronePopupStats : function(userId)
  {
    var t = Tabs.Range;

    delete t.baseStats[userId];
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  populateStatsPopup : function(userId, throneStats)
  {
    var t = Tabs.Range;
    
    if(throneStats == undefined)
    {
      return;
    }

    if(t.baseStats[userId] == undefined)
    {
      t.baseStats[userId] = {};
      
      for(statId in throneStats)
      {
        t.baseStats[userId][statId] = throneStats[statId].percent;
      }
    }
    
    var m = '';
    m += '<table class=trStatTab>';
    m += '<tr>';
    m += '<th>Boost</th><th>Value</th>';
    m += '</tr>';

    for(statId in throneStats)
    {
      var style='';
      
      boost = throneStats[statId];

      if(t.baseStats[userId][statId] == undefined || t.baseStats[userId][statId].percent < boost.percent)
      {
        style = ' class=redLine'
      }
      
      m += '<tr>';
      m += '<td' + style + '>' + boost.name + '</td><td' + style + '>' + boost.percent + '</td>';
      m += '</tr>';
    }
    
    var now = new Date();

    D = t.addZero(now.getDate());
    M = t.addZero(now.getMonth() + 1);
    Y = t.addZero(now.getFullYear());
    hours = t.addZero(now.getHours());
    mins = t.addZero(now.getMinutes());
    secs = t.addZero(now.getSeconds());
    
    // var time =  D +"/"+ M +"/"+ Y +"  "+ h + ":" + m;
    var time =  hours + ":" + mins + ":" + secs;

    m += '<tr>';
    m += '<td colspan=2>';
    m += 'Updated: ' + time;
    m += '</td>';
    
    m += '</tr>';
    m += '</table>';
    
    jQuery('#throneStatsUpdatePopup' + userId).html(m);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  closeThronePopup : function(userId)
  {
    var t = Tabs.Range;
    
    logit("Popup: try and kill the timers");
    clearInterval(t.displayUpdateTime);
    clearInterval(t.rangeUpdateTimer[userId]);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  instantUpdate: function(data)
  {
    var t = Tabs.Range;

    if(Options.attackersRange[data.user.id] != undefined)
    {
      Options.attackersRange[data.user.id].name = data.user.username;
      Options.attackersRange[data.user.id].alliance = data.alliance.name;
      
      t.fetchPlayerThrone(data.user.id, t.updateRange, true);
      
      t.updateRequired = true;
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _updateTable: function()
  {
    var t = Tabs.Range;
    var m = "";
    
    m += "<table class=trStatTab>";
    
    m += "<tr>";
    m += "<th colspan='3'></th><th colspan='6' align=center>Ranges</th>";
    if(t.showUpdateTime)
    {
      m += "<th rowspan='2'>-</th>";   
    }
    m += "</tr>"; 
    m += "<tr>";
    m += "<th colspan='2'>Player</th><th colspan='1'></th><th colspan='2'>Range</th><th colspan='2'>Siege Range</th><th colspan='2'>Ranged Range</th>";   
    m += "</tr>"; 
    
    jQuery.each(Options.attackersRange, function(i, val) 
    {
      if((parseIntWithDefault(val.range,0) + parseIntWithDefault(val.rangeDebuff,0)) < t.hideBelow)
      {
        return true; // we dont want to display this, return true in each loop is like a break
      }
      
      alliance = val.alliance ? val.alliance : "";
      name = val.name ? val.name : "";
      
      var regex = new RegExp(t.nameMatch, "i")

      if(t.nameMatch && name.search(regex) == -1 && alliance.search(regex) == -1)
      {
        return true;
      }
      
      if(i == parseInt(uW.tvuid))
      {
        return true;
      }
      
      m += "<tr id='rtRow_" + i + "'>";
      m += t._createRow(i, val);
      m += "</tr>";
    });
    
    m += "</table>";
    
    jQuery('#rangeTable').html(m); 
    
    jQuery('[id^=rtPeriod_]').change(function() 
    {
      var row = parseInt(this.id.substr(9));
      if(Options.attackersRange[row])
      {
        Options.attackersRange[row].updatePeriod = this.value;
        Options.attackersRange[row].periodUpdated = true;
        logit("Range: update check period [" + row + "] - " + this.value + " " + this.id);
      }
    });
    
    jQuery('[id^=rtPeriod_]').each(function(index) 
    {
      var row = parseInt(this.id.substr(9));
      var updatePeriod = 12;
      
      if(Options.attackersRange[row])
      {
        if(Options.attackersRange[row].updatePeriod)
        {
          updatePeriod = Options.attackersRange[row].updatePeriod;
        }
      }
      
      jQuery(this).val(updatePeriod); 
    });

    var moveDown = 20;
    var moveLeft = 20;

    jQuery('[id^=rtName_]').click(function() 
    {
      var playerId = parseInt(this.id.substr(7));
      
      if(Options.attackersRange[playerId])
      {
        var data = {};
        data.user = {};
        data.user.id = playerId;

        t.quickMonitorUser(data);
      }
    });
    
    jQuery('[id^=rtName_]').hover(function(e) 
    {
      var row = parseInt(this.id.substr(7));
      
      if(Options.attackersRange[row])
      {
        jQuery('div#range_pop-up').html(t._createPopup(row, t.compareSlot));
      }
      
      jQuery('div#range_pop-up').show()
        .css('top', e.pageY + moveDown)
        .css('left', e.pageX + moveLeft)
        .css('z-index', 999999)
        .appendTo('body');
    }, function() {
      jQuery('div#range_pop-up').hide();
    });

    jQuery('[id^=rtName_]').mousemove(function(e) {
      jQuery('div#range_pop-up').css('top', e.pageY + moveDown).css('left', e.pageX + moveLeft);
    });

    jQuery('#rangeRecordsShowing').text(jQuery('[id^=rtName_]').length);
    
    t.updateRequired = false;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _updateRow: function(row, val)
  {
    var t = Tabs.Range;

    var m = t._createRow(row, val);

    jQuery('#rtRow_' + row).html(m);  
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _createPopup: function(row, compareSlot)
  {
    var t=Tabs.Range;
    
    compareSlot = compareSlot | Seed.throne.activeSlot;
    
    myStats = t.myThroneStats(compareSlot);
    
    var liveStats = undefined;
    
    if(compareSlot != Seed.throne.activeSlot)
    {
      liveStats = t.myThroneStats(Seed.throne.activeSlot);
    }
    else
    {
      liveStats = myStats;
    }
    
    var m = "";
    
    if(Options.attackersRange[row])
    {
      attackerStats = Options.attackersRange[row];

      // TODO we can maybe refactor this so we dont calcrange of troops in lots of places and only recalc when something has changed?
      
      var defCatRange = troopRange(myStats, attackerStats, 12, t.assumeDefenderSacrifice);
      var defBallRange = troopRange(myStats, attackerStats, 10, t.assumeDefenderSacrifice);
      var defArcherRange = troopRange(myStats, attackerStats, 6, t.assumeDefenderSacrifice);
      var attCatRange = troopRange(attackerStats, myStats, 12, t.assumeAttackerSacrifice);
      var attBallRange = troopRange(attackerStats, myStats, 10, t.assumeAttackerSacrifice);
      var attArcherRange = troopRange(attackerStats, myStats, 6, t.assumeAttackerSacrifice);

      if(SessionOptions.attackersRange[row])
      {
        var liveAttackerStats = SessionOptions.attackersRange[row];
        var liveDefCatRange = troopRange(liveStats, liveAttackerStats, 12, t.assumeDefenderSacrifice);
        var liveDefBallRange = troopRange(liveStats, liveAttackerStats, 10, t.assumeDefenderSacrifice);
        var liveDefArcherRange = troopRange(liveStats, liveAttackerStats, 6, t.assumeDefenderSacrifice);
        var liveAttCatRange = troopRange(liveAttackerStats, liveStats, 12, t.assumeAttackerSacrifice);
        var liveAttBallRange = troopRange(liveAttackerStats, liveStats, 10, t.assumeAttackerSacrifice);
        var liveAttArcherRange = troopRange(liveAttackerStats, liveStats, 6, t.assumeAttackerSacrifice);
      }

      t._lastUpdateDisplay(attackerStats.lastChecked)
      
      m += "<table>";
      m += "<tr>";
      m += "<td>Name:</td><td>" + (attackerStats.name != undefined ? attackerStats.name : '------') + "</td>";
      m += "</tr>";
      m += "<tr>";
      m += "<td>Alliance:</td><td>" + (attackerStats.alliance != undefined ? attackerStats.alliance : '------') + "</td>";
      m += "</tr>";
      m += "<tr>";
      m += "<td>Last Update :</td><td>" + t._lastUpdateDisplay(attackerStats.lastChecked) + "</td>";
      m += "</tr>";
      m += "</table>";
      m += "<br>";
      m += "<table class='trStatTab'>";
      m += "<tr>";
      m += "<th>Troop Type</th><th>Them</th><th>Us</th>";
      if(SessionOptions.attackersRange[row])
      {
        m += "<th>Them (Live)</th><th>Us (Live)</th>";
      }
      m += "</tr>";
      m += "<tr>";
      m += "<th>Archers</th><td>"+ attArcherRange + "</td><td>" + defArcherRange + " </td>";
      if(SessionOptions.attackersRange[row])
      {
        m += "<td>"+ liveAttArcherRange + "</td><td>" + liveDefArcherRange + " </td>";
      }
      m += "</tr>";
      m += "<tr>";
      m += "<th>Ballista</th><td>"+ attBallRange + "</td><td>" + defBallRange + " </td>";
      if(SessionOptions.attackersRange[row])
      {
        m += "<td>"+ liveAttBallRange + "</td><td>" + liveDefBallRange + " </td>";
      }
      m += "</tr>";
      m += "<tr>";
      m += "<th>Catapults</th><td>"+ attCatRange + "</td><td>" + defCatRange + " </td>";
      if(SessionOptions.attackersRange[row])
      {
        m += "<td>"+ liveAttCatRange + "</td><td>" + liveDefCatRange + " </td>";
      }
      m += "</tr>";
      m += "</table>"
      //m += "<br><div width='90%'><br> The values shown are for guidance only and may change depending on exact tr items used during attack and defending</div>";
    }
    
    return m;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _createRow: function(row, val)
  {
    var t = Tabs.Range;
    var m = "";
    var rowClass = "greenLine";
    
    var battleResult = t.checkRanges(t.myStats, val);
    
    val.battleResult = battleResult;
    
    switch(battleResult)
    {
      case 2: // his archers win
        rowClass = "redLine";
        break;
      case 1: // his cats win
        rowClass = "yellowLine";
        break;
      case 10: // our archers win
        rowClass = "blueLine";
        break;
    }
    try
    {
      m += "<td id='rtName_" + row + "' class=" + rowClass + ">" + ((val.name != undefined && val.name) ? val.name.substring(0, 10) : "---") + "</td>";
    }
    catch (e)
    {
      m += "<td id='rtName_" + row + "' class=" + rowClass + ">" + "---" + "</td>";
    }
    try
    {
      m += "<td id='rtAlliance_" + row + "' class=" + rowClass + ">" + ((val.alliance != undefined && val.alliance) ? val.alliance.substring(0, 10) : "---") + "</td>";
    }
    catch(e)
    {
      m += "<td id='rtAlliance_" + row + "' class=" + rowClass + ">" + "---" + "</td>";
    }
    m += "<td id='rtLastUpdate_" + row + "' class=" + rowClass + ">" + t._lastUpdateDisplay(val.lastChecked) + "</td>";
    m += "<td class=" + rowClass + ">" + (val.range != undefined ? val.range : "---") + "</td>";
    m += "<td class=" + rowClass + ">" + (val.rangeDebuff != undefined ? val.rangeDebuff : "---") + "</td>";
    m += "<td class=" + rowClass + ">" + (val.siegeRange != undefined ? val.siegeRange : "---") + "</td>";
    m += "<td class=" + rowClass + ">" + (val.siegeRangeDebuff != undefined ? val.siegeRangeDebuff : "---") + "</td>";
    m += "<td class=" + rowClass + ">" + (val.rangedRange != undefined ? val.rangedRange : "---") + "</td>";
    m += "<td class=" + rowClass + ">" + (val.rangedRangeDebuff != undefined ? val.rangedRangeDebuff : "---") + "</td>"
    
    if(t.showUpdateTime)
    {
      m += "<td class=" + rowClass + "><select id='rtPeriod_" + row + "'>";
      m += '<option value="1">1h</option>';
      m += '<option value="3">3h</option>';
      m += '<option value="6">6h</option>';
      m += '<option value="12">12h</option>';
      m += '<option value="24">1d</option>';
      m += '<option value="48">2d</option>';
      m += '<option value="60">2.5d</option>';
      m += '<option value="120">5d</option>';
      m += '<option value="168">1w</option>';
      m += '<option value="672">4w</option>';
      m += "</select></td>";
      
      if(val.periodUpdated)
      {
        jQuery('#rtPeriod_' + row).css("color", '#CCCCCC');
      }
    }

    return m;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  _lastUpdateDisplay: function(lastUpdate)
  {
    var now = unixTime();
    var timeSinceUpdate = parseInt(parseInt(now) - parseInt(lastUpdate));
    var units = "";
    
    if(lastUpdate == undefined || lastUpdate == 0)
    {
      return "---";
    }
    
    if(timeSinceUpdate > 60)
    {
      timeSinceUpdate /= 60;
      
      if(timeSinceUpdate > 60)
      {
        timeSinceUpdate /= 60;

        if(timeSinceUpdate > 24)
        {
          timeSinceUpdate /= 24;

          if(timeSinceUpdate > 7)
          {
            timeSinceUpdate /= 7;
            units = "w";
          }
          else
          {
            units = "d";
          }
        }
        else
        {
          units = "h";
        }
      }
      else
      {
        units = "m";
      }
    }
    else
    {
      units = "s";
    }
    
    return Math.floor(timeSinceUpdate) + units;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide : function ()
  {
    var t = Tabs.Range;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {
    var t = Tabs.Range;
    
    if(t.updateRequired)
    {
      t._updateTable();
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fetchPlayerThrone: function (aid, notify, priority) 
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    priority = priority || false;
    instant = priority || false;
    
    if(!Options.FullEnable)
      return;
    
    if(aid == unsafeWindow.tvuid)
      return;

    logit("Range: get range - " + aid);
    params.ctrl = "throneRoom\\ThroneRoomServiceAjax";
    params.action = "getEquipped";
    params.playerId = aid;

    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch53.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      priority: priority,
      instant: instant,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");
        
        if(rslt.ok)
        {
          logit("Range: read player range - " + aid);
          var items = rslt.items;
          
          if(!playerThroneItems[aid])
          {
            playerThroneItems[aid] = {};
          }
  
          for(itemNumber = 0 ; itemNumber < items.length ; itemNumber++)
          {
            playerThroneItems[aid][items[itemNumber].id] = items[itemNumber];
          }
          
          savePlayerThrone();

          notify(aid, items);
        }
      },
      
      onFailure: function()
      {
        logit("Range: error reading throne stats - " + aid);
      },
    }, false);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fetchPlayerInfo : function (uid, notify)
  {
    var params = uW.Object.clone(uW.g_ajaxparams);
    params.uid = uid;
    
    new AjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");

        notify (rslt);
        
        logit("PlayerInfo: - " + JSON2.stringify(rslt,null,2));
      },
      
      onFailure: function (rslt) 
      {
        logit("Range: error reading player info - " + uid);
        notify ({errorMsg:'AJAX error'});
      },
    });
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fetchAllianceList : function (pageNum, notify)
  {
    var t = Tabs.Range;
    
    var params = uW.Object.clone(uW.g_ajaxparams);

    params.pageNo = pageNum;
    params.cityId = uW.currentcityid;
    
    new PriorityAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetOtherInfo.php" + uW.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,

      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");

        logit("Range: read alliance list");
        notify (rslt);
      },
      
      onFailure: function (rslt) 
      {
        logit("Range: error reading alliance list");
        notify ({errorMsg:'AJAX error'});
      },
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  fetchAllianceMemberList : function (allianceId, allianceName, notify) 
  {
    var params = uW.Object.clone(uW.g_ajaxparams);

    params.perPage = 100;

    if (allianceName)
    {
      params.allianceName = allianceName;
    }
    
    if (allianceId && allianceId != 0)
    {
      params.allianceId = allianceId;
    }
    
    logit("Range: Alliance ID - " + allianceId);
    
    params.type = 'might';
    params.page = 1;
    
    new AjaxRequest(uW.g_ajaxpath + "ajax/getUserLeaderboard.php" + uW.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (transport) 
      {
        var rslt = eval("(" + transport.responseText + ")");

        notify (rslt);
      },
      
      onFailure: function (rslt) {
        logit("Range: error reading alliance member list");
        notify ({errorMsg:'AJAX error'});
      },
    });
  },
}


/*********************************** ATTACK TAB ***********************************/
function setMaxHeightScrollable (e){
  e.style.height = '100%';
  e.style.height = e.clientHeight + 'px';
  //e.style.maxHeight = e.clientHeight + 'px';
  e.style.overflowY = 'auto';
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Attack
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Attack = {
  tabDisabled : !ENABLE_ATTACK_TAB,
  tabOrder: 500,
  myDiv : null,
  data : {},  
  MapAjax : new CMapAjax(),
    
  init : function (div){
    var t = Tabs.Attack;
    t.myDiv = div;
    t.myDiv.innerHTML = '<TABLE width=100% height=100% class=pbTab><TR><TD><INPUT id=pbBarbShow type=submit value="Show All Targets" \> <BR>\
       City: <SPAN id=pbAtkCSS></span> &nbsp; &nbsp; &nbsp; Radius: <INPUT id=pbBarbDist size=3 type=text> &nbsp; &nbsp; <INPUT id=pbBarbScan type=submit value=Scan \></td></tr><TR><TD height=100%>\
       <DIV id=pbAtkDiv style="background-color:white"></div></td></tr></table>';
    t.loadTargets ();
    // TODO: Check current cities, invalidate data if city moved
    document.getElementById('pbBarbScan').addEventListener ('click', t.e_clickedScan, false);
    document.getElementById('pbBarbShow').addEventListener ('click', t.e_clickedShow, false);
    new CdispCityPicker ('pbAtkCS', document.getElementById('pbAtkCSS'), false, function (c){t.scanCity=c}, 0);
  },
  
  hide : function (){
  },

  state : 0,
  show : function (){
    var t = Tabs.Attack;
    if (t.state == 0){
      setMaxHeightScrollable (document.getElementById('pbAtkDiv'));
      t.state = 1;
    }
  },

  clearDiv : function (){
    document.getElementById('pbAtkDiv').innerHTML = '';
  },
  writeDiv : function (m){
    document.getElementById('pbAtkDiv').innerHTML += m;
  },
  
  loadTargets : function (){
    var t = Tabs.Attack;
    DebugTimer.start();
    var totTargets = 0; 
    
    for (var c=0; c<Cities.numCities; c++){
      var s = GM_getValue ('atk_'+ getServerId() +'_'+ Cities.cities[c].id, null);

      if (s == null) {
        t.data['city'+ Cities.cities[c].id] = {cityX:Cities.cities[c].x, cityY:Cities.cities[c].y, radius:0, numTargets:0, targets:{}};
      } else {
        t.data['city'+ Cities.cities[c].id] = JSON2.parse (s);
      }
      
      totTargets += t.data['city'+ Cities.cities[c].id].numTargets;
    }
    
    DebugTimer.display ('Time to GM_getValue() '+ totTargets +' targets for all cities');    
  },
  
  e_clickedScan : function (){
    var t = Tabs.Attack;
    t.clearDiv();
    var dist = parseInt(document.getElementById('pbBarbDist').value);
    
    if (isNaN(dist) || dist<1 || dist>35) {
      t.writeDiv ("<SPAN class=boldRed>Nuh-uh, try again</span><BR>");
      return;
    }
    
    t.writeDiv ('Scanning map for city: '+ t.scanCity.name +'<BR>');
    t.scanBarbs (t.scanCity.id, dist);
  },

  popShow : null,  
  
  e_clickedShow : function (){    // show all current attack data
    var t = Tabs.Attack;
    
    if (t.popShow == null){
      t.popShow = new pbPopup ('pbbs', 0,0, 500,500, true, function (){t.popShow.destroy(); t.popShow=null;});
      t.popShow.centerMe (mainPop.getMainDiv());  
    }
    
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 class=pbTabPad>';
    
    for (var c=0; c<Cities.numCities; c++) {
      var dat = t.data['city'+ Cities.cities[c].id];
      m += '<TR><TD colspan=3><DIV class=pbStat>'+ Cities.cities[c].name +' &nbsp; (radius:'+ dat.radius +' &nbsp;targets:'+ dat.numTargets  +')</div></td></tr>';
      // sort by distance ...
      var atks = [];
      
      for (k in dat.targets) {
        atks.push (dat.targets[k]);
      }
      
      atks.sort (function(a,b){return a.dist-b.dist});     
      
      for (i=0; i<atks.length; i++) {
        m += '<TR><TD>Barb Camp '+ atks[i].lvl +'</td><TD>'+ atks[i].x +','+ atks[i].y +'</td><TD> &nbsp; Dist='+ atks[i].dist.toFixed(2) +'</td></tr>';
      }
    } 
    
    t.popShow.getMainDiv().innerHTML = '</table></div>'+ m;
    t.popShow.getTopDiv().innerHTML = '<CENTER><B>Showing all targets in memory</b></center>';
    t.popShow.show(true);    
  },

  configWriteTargets : function (cityID){
    var t = Tabs.Attack;
    var serverID = getServerId();
    DebugTimer.start();    
    GM_setValue ('atk_'+ serverID +'_'+ cityID,  JSON2.stringify(t.data['city'+ cityID]));
    t.writeDiv ('** Time to GM_setValue() '+ t.data['city'+ cityID].numTargets +' targets for city: '+ (DebugTimer.getMillis()/1000) +' seconds<BR>');
  },
    
  oScan : {},   
    scanBarbs : function (cityID, distance){   // max distance:35
    var t = Tabs.Attack;
    var city = Cities.byID[cityID];
    // TODO: remember state - in case of refresh
    var x = t.MapAjax.normalize(city.x-distance);
    var y = t.MapAjax.normalize(city.y-distance);
    t.oScan = { city:city, centerX:city.x, centerY:city.y, maxDist:distance,
        minX:x, maxX:city.x+distance, minY:y, maxY:city.y+distance, curX:x, curY:y, data:[] };
    setTimeout (function(){t.MapAjax.request (t.oScan.curX, t.oScan.curY, 15, t.e_mapCallback)}, MAP_DELAY);
    t.writeDiv ('Scanning @ '+ t.oScan.curX +','+ t.oScan.curY +'<BR>');
  },

  e_scanDone : function (errMsg){
    var t = Tabs.Attack;
    t.data['city'+ t.oScan.city.id] = {cityX:t.oScan.city.x, cityY:t.oScan.city.y, radius:t.oScan.maxDist, numTargets:0, targets:{}};
    var dat = t.data['city'+ t.oScan.city.id];
    t.writeDiv ('Done scanning<BR>');
    
    for (var i=0; i<t.oScan.data.length; i++){
      var map = t.oScan.data[i];
      dat.targets[map[0] +'_'+ map[1]] = {type:'b', x:map[0], y:map[1], dist:map[2], lvl:map[3]};
      ++dat.numTargets;
    }
    
    t.configWriteTargets (t.oScan.city.id);
  },
      
  e_mapCallback : function (left, top, width, rslt){
    var t = Tabs.Attack;
    
    if (!rslt.ok){
      setTimeout (function(){t.e_scanDone (rslt.errorMsg)}, 0);
      t.writeDIV ('<BR>ERROR: '+ rslt.errorMsg +'<BR>');
      return;
    }
    
    var map = rslt.data;
    for (k in map) {
      var lvl = parseInt(map[k].tileLevel);
      
      if (map[k].tileType==51 && !map[k].tileCityId && lvl<8) {  // if barb
        var dist = distance (t.oScan.centerX, t.oScan.centerY, map[k].xCoord, map[k].yCoord);
      
        if (dist <= t.oScan.maxDist){
          t.oScan.data.push ([parseInt(map[k].xCoord), parseInt(map[k].yCoord), dist, lvl]);
        }
      }
    }
    
    t.oScan.curX += 15;
    
    if (t.oScan.curX > t.oScan.maxX) {
      t.oScan.curX = t.oScan.minX;
      t.oScan.curY += 15;
      
      if (t.oScan.curY > t.oScan.maxY) {
        setTimeout (function(){t.e_scanDone (null)}, 0);
        return;
      }
    }

    var x = t.oScan.curX;
    var y = t.oScan.curY;

    setTimeout (function(){t.MapAjax.request (x,y, 15, t.e_mapCallback)}, MAP_DELAY);
    t.writeDiv ('Scanning @ '+ x +','+ y +'<BR>');
  },
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Test
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Test = {
  tabOrder: 975,
  tabDisabled : true,         // if true, tab will not be added or initialized
  tabLabel : 'Test',
  myDiv : null,

  init : function (div){
    var t = Tabs.Test;
    t.myDiv = div;
    var m = '<TABLE><TR><TD align=right>Scout: </td><TD><INPUT type=checkbox id=pbfakeIsScout></td></tr>\
        <TR><TD align=right>Wild: </td><TD><INPUT type=checkbox id=pbfakeIsWild></td></tr>\
        <TR><TD align=right>False Report: </td><TD><INPUT type=checkbox id=pbfakeFalse></td></tr>\
        <TR><TD align=right>Seconds: </td><TD><INPUT type=text size=4 value=300 id=pbfakeSeconds></td></tr>\
        <TR><TD align=right># of Militia: </td><TD><INPUT type=text size=6 value=5000 id=pbfakeMilitia></td></tr>\
        <TR><TD colspan=2 align=center><INPUT id=pbtestSendMarch type=submit value="Fake Attack" \></td></tr></table>\
        <BR><INPUT id=pbReloadKOC type=submit value="Reload KOC" \>\
        <BR><INPUT id=dumpSeed type=submit value="Dump Seed" \>\
        <BR><INPUT id=dumpThrone type=submit value="Dump Throne Items" \>\
        <BR><INPUT id=dumpItems type=submit value="Dump Item List" \>\
        <BR><INPUT id=dumpUnsafeWindow type=submit value="Dump Unsafe Window (CM)" \>\
        <BR><INPUT id=dumpGuardian type=submit value="Dump Guardian" \>\
        <BR><INPUT id=dumpOptions type=submit value="Dump Options" \>\
        <BR><INPUT id=dumpUnitStats type=submit value="Dump Unit Stats" \>\
        <BR><INPUT id=dumpUnitCosts type=submit value="Dump Unit Costs" \>\
        <BR><INPUT id=dumpPlayerThrone type=submit value="Dump Player Throne" \>\
        <BR><INPUT id=dumpPlayerRange type=submit value="Dump Player Range" \>\
        <BR><INPUT id=updateSeed type=submit value="Force Seed Update" \>\
        <BR><INPUT id=clearPlayerThrone type=submit value="Clear Player Throne" \>\
        <BR><INPUT id=viewRequestQueue type=submit value="View Request Queue" \>\
        <BR>Force ajax errors : <INPUT type=checkbox id=pbajaxErr>\
        <BR>Send alliance chat alert as whisper : <INPUT type=checkbox id=pbalertWhisper>\
        <BR><DIV id=pbtestDiv style="background-color:#ffffff; maxwidth:675; maxheight:350px; height:350px; overflow-y:auto;"></div>';
    
    div.innerHTML = m;
    
    document.getElementById('pbtestSendMarch').addEventListener ('click', t.clickFakeAttack, false);
    document.getElementById('pbReloadKOC').addEventListener ('click', reloadKOC, false);
    document.getElementById('dumpSeed').addEventListener ('click', t.dumpSeed, false);
    document.getElementById('dumpThrone').addEventListener ('click', t.dumpThrone, false);
    document.getElementById('dumpUnsafeWindow').addEventListener ('click', t.dumpUnsafeWindow, false);
    document.getElementById('dumpGuardian').addEventListener ('click', t.dumpGuardian, false);
    document.getElementById('dumpOptions').addEventListener ('click', t.dumpOptions, false);
    document.getElementById('dumpItems').addEventListener ('click', t.dumpItems, false);
    document.getElementById('dumpUnitStats').addEventListener ('click', t.dumpUnitStats, false);
    document.getElementById('dumpUnitCosts').addEventListener ('click', t.dumpUnitCosts, false);
    document.getElementById('dumpPlayerThrone').addEventListener ('click', t.dumpPlayerThrone, false);
    document.getElementById('dumpPlayerRange').addEventListener ('click', t.dumpPlayerRange, false);
    document.getElementById('viewRequestQueue').addEventListener ('click', t.viewRequestQueue, false);
    document.getElementById('updateSeed').addEventListener ('click', t.updateSeed, false);
    document.getElementById('clearPlayerThrone').addEventListener ('click', t.clearPlayerThrone, false);
    document.getElementById('pbajaxErr').addEventListener ('click', function (){window.EmulateAjaxError=this.checked}, false);
    document.getElementById('pbalertWhisper').addEventListener ('click', function (){SEND_ALERT_AS_WHISPER=this.checked}, false);
  },

  dumpSeed : function () 
  {
    logit("Dump: Seed -" + JSON2.stringify(Seed, null, 2));
  },
  
  viewRequestQueue : function () 
  {
    popShowRequestQueue = new pbPopup('pbShowTrade', 0, 0, 750, 485, true, function() {clearTimeout (1000);});
    var m = '<DIV style="overflow-y:auto" id=showScheduleQueue></div>';       
    popShowRequestQueue.getMainDiv().innerHTML = m;
    popShowRequestQueue.getTopDiv().innerHTML = '<TD><CENTER><B>'+translate("Request Queue")+'</b></center></td>';
    popShowRequestQueue.autoHeight (true);  
    popShowRequestQueue.autoWidth (true);  
    popShowRequestQueue.show(true);
    
    var m = '';
    
    m += '<table class=trStatTab>';
    m += '<tr>';
    m += '<th>URL</th><th>Type</th><th>March</th>';
    m += '</tr>';

    for(i = 0 ; i < RequestData.Queue.length ; i++)
    {
      m += '<tr>';
      m += '<td>' + RequestData.Queue[i].url + '</td><td>' + RequestData.Queue[i].type + '</td><td>' + RequestData.Queue[i].march+ '</td>';
      m += '</tr>';
    }
    
    // var now = new Date();

    // D = t.addZero(now.getDate());
    // M = t.addZero(now.getMonth() + 1);
    // Y = t.addZero(now.getFullYear());
    // hours = t.addZero(now.getHours());
    // mins = t.addZero(now.getMinutes());
    // secs = t.addZero(now.getSeconds());
    
    // var time =  D +"/"+ M +"/"+ Y +"  "+ h + ":" + m;
    // var time =  hours + ":" + mins + ":" + secs;

    // m += '<tr>';
    // m += '<td colspan=3>';
    // m += 'Updated: ' + time;
    // m += '</td>';
    
    // m += '</tr>';
    m += '</table>';
    
    jQuery('#showScheduleQueue').html(m);
  },

  dumpOptions : function () {
    logit("Dump: Options -" + JSON2.stringify(Options, null, 2));
  },

  dumpItems : function () {
    logit("Dump: Options -" + JSON2.stringify(unsafeWindow.ksoItems, null, 2));
  },
  
  dumpUnitStats : function () {
    logit("Dump: Options -" + JSON2.stringify(unsafeWindow.unitstats, null, 2));
  },
  
  dumpUnitCosts : function () {
    logit("Dump: Options -" + JSON2.stringify(unsafeWindow.unitcost, null, 2));
  },
  
  dumpUnsafeWindow : function () {
    logit("Dump: CM -" + JSON2.stringify(CM, null, 2));
  },
  
  dumpThrone : function () {
    logit("Dump: Throne Items -" + JSON2.stringify(unsafeWindow.kocThroneItems, null, 2));
  },

  dumpPlayerThrone : function () {
    logit("Dump: Throne Items -" + JSON2.stringify(playerThroneItems, null, 2));
  },

  dumpPlayerRange : function () {
    logit("Dump: Throne Items -" + JSON2.stringify(Options.attackersRange, null, 2));
  },

  clearPlayerThrone : function () {
    playerThroneItems = {};
  },

  updateSeed : function () 
  {
    setTimeout(function()
    {
      unsafeWindow.update_seed_ajax(true, function() {return;} );
    }, 250);
  },
  
  dumpGuardian : function () 
  {
    var t = Tabs.Test;
    logit("Guardian");
    logit(JSON2.stringify(Seed.guardian,null,2));
    
    for(i=0; i<Seed.cities.length; i++) 
    {
      for(g=0;g<Seed.guardian.length;g++) 
      {
        if (Seed.guardian[g]['cityId'] == Seed.cities[i][0] && Seed.guardian[g].level != 0 && Seed.guardian[g].type != "wood") 
        {
          logit("Guardian Type - " + Seed.guardian[g].type);
          logit("tvuid - " + unsafeWindow.tvuid);
          
          if(i == 0)
            t.summon(Seed.cities[i][0]);
        }
      }
    }
  },
  
  summon: function (city) 
  {
    Tabs.tower.doSummon(unsafeWindow.currentcityid);
  },

  hide : function ()
  {
    var t = Tabs.Test;
  },

  show : function ()
  {
  },

  writeDiv : function (msg)
  {
    var t = Tabs.Test;
    document.getElementById('pbtestDiv').innerHTML = msg;
  },

  addDiv : function (msg)
  {
    var t = Tabs.Test;
    document.getElementById('pbtestDiv').innerHTML += msg;
  },
  
  createFakeAttack : function (cityNum, isScout, isWild, isFalse, secs, numMilitia)
  {
    var marchId = 'm'+ (88888 + Math.floor(Math.random()*11111));
    var march = {};
    
    if (matTypeof(Seed.queue_atkinc)=='array') 
    {
      Seed.queue_atkinc = {};
    }
    
    if (isFalse) {
      march.marchType = 0;
    } else if (isScout) {
      march.marchType = 3;
    } else {
      march.marchType = 4;
    }

    march.toCityId = Cities.cities[cityNum].id;

    if (isWild) {
      keys = unsafeWindow.Object.keys(Seed.wilderness['city'+Cities.cities[cityNum].id]);
      march.toTileId = Seed.wilderness['city'+Cities.cities[cityNum].id][keys[0]].tileId;
    } else {
      march.toTileId = Cities.cities[cityNum].tileId;
    }

    secs = parseInt(secs);

    march.arrivalTime = unixTime() + secs;
    march.departureTime = unixTime() - 10;
    march.unts = {}
    march.unts.u3 = 1
    march.unts.u2 = numMilitia
    march.pid = 1234567
    march.score = 9
    march.mid = marchId.substr(1);
    march.players = {}
    march.players.u1234567 = {}
    march.players.u1234567.n = 'Fred Flintstone';
    march.players.u1234567.t = 60
    march.players.u1234567.m = 5441192
    march.players.u1234567.s = 'M';
    march.players.u1234567.w = 1
    march.players.u1234567.a = 1
    march.players.u1234567.i = 5
    Seed.queue_atkinc[marchId] = march;
    Seed.players.u1234567 = march.players.u1234567;
  },

  clickFakeAttack : function (){
    var t = Tabs.Test;
    var isScout = document.getElementById('pbfakeIsScout').checked;
    var isWild = document.getElementById('pbfakeIsWild').checked;
    var isFalse = document.getElementById('pbfakeFalse').checked;
    var secs = parseInt(document.getElementById('pbfakeSeconds').value);
    var mil = parseInt(document.getElementById('pbfakeMilitia').value);
    t.createFakeAttack (0, isScout, isWild, isFalse, secs, mil);
  },
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: March
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.March = 
{
  tabOrder: 102,
  myDiv: null,
  displayTimer : null,
  tabLabel : 'March',
  state : null,
  curTabBut : null,
  curTabName : null,
  sourceCity : {},
  destinationCity : {},
  rows : [],
  iused : new Array(),

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init : function (div)
  {
    var t = Tabs.March;
    t.myDiv = div;
    t.state = null;
    clearInterval (t.displayTimer);
    
    t.getAllianceMembersList();
    
    setInterval(t.getAllianceMembersList, 10 * 60 * 1000);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getContent : function ()
  {
    var t = Tabs.March;
    
    return t.myDiv;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide : function ()
  {
    var t = Tabs.March;
    
    t.state = null;
    
    clearInterval (t.displayTimer);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {  
    var t = Tabs.March;
    
    if (t.state == null) 
    {  
      m = "<DIV class=pbStat><b>QUICK MARCH TOOL</b></div>";
      m += "<TABLE width=600 class=ptTab border=0 align=center>\
           <tr><td colspan=4 align=center><input type=button id=REEaction value='Scout'>&nbsp;<input type=button id=RAAaction value='Attack'>&nbsp<input type=button id=RARaction value='Reassign'>&nbsp;<input type=button id=RENaction value='Reinforce'>&nbsp;<input type=button id=RENBaction value='Reinforce + Max Food'>&nbsp;<input type=button id=RCNLaction value='Cancel'></td></tr>\
           <tr align=center valign=top>\
           <td><b><u>Source</b></u><br><span id=pbSourceCity></span></td>\
           <td><b><u>Destination</b></u><br>X:<input type=text id=RAAtypetrpx size=3>&nbsp;Y:<input type=text id=RAAtypetrpy size=3></td>\
           <td><b><u>Distance</u></b><br><span id='BOEstimationD'>&nbsp;</span></td>\
           <td><b><u>Destination City Shortcut</u></b><br><span id=pbDestinationCity></span></td>\
           </tr>\
           <tr>\
           <td colspan=4 align=center>Alliance Destinations : <select id='pbMarchAllianceList'><option value=''>Selection...</option></select></td>\
           </tr>\
           <tr align=center valign=top>\
           <td colspan=4>\
           <table border=0 bordercolor=black style='text-align:center; border-spacing: 40px 0px;'>\
           <tr>\
           <td><b>Units Available</b></td>\
           <td><b><a href='javascript:void(0)' id=BO_RAZ_Units title='Clear' >Units Selected</a></b></td>\
           <td><b>Attack Time</b></td>\
           <td><b>Reinforce Time</b></td>\
           </tr>";

      var r = 1;
      for(unit in unsafeWindow.unitcost)
      {
        m += '<tr>';
        m += '<td align=right style="vertical-align:middle"><img style="vertical-align:middle" title="' + unsafeWindow.unitcost[unit][0] + '" height=20 src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_'+r+'_30_s34.jpg>';
        m += '<input style="border:1px solid black;height:18px;font-size:11px;" id="RAAdestunit'+r+'" type=text size=7 readonly value="0">&nbsp;&nbsp;&nbsp;&nbsp;';
        m += '<input type=button value="--->" id="RAApdestunit'+r+'"  style="border:1px solid black;height:18px;font-size:11px;"></td>';
        m += '<td align=right style="vertical-align:middle"><img style="vertical-align:middle" height=20 title="' + unsafeWindow.unitcost[unit][0] + '" src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_'+r+'_30_s34.jpg>';
        m += '<input style="border:1px solid black;height:18px;font-size:11px;" id="RAAnbunit' + r + '" type=text size=7 value="0" ></td>';
        m += '<td style="vertical-align:middle"><span id="BOEstimationTT' + r + '">&nbsp;</span></td>';
        m += '<td style="vertical-align:middle"><span id="BOEstimationTZ' + r + '">&nbsp;</span></td>';
        m += '</tr>';

        r++;
      }
      m += "</table></td></tr>";
      
      var itemlist = [55, 57, 931, 932];
      
      var BOitems="";
      
      for(var i = 0 ; i < itemlist.length ; i++)
      {
        BOitems += "<img src='http://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/30/" + itemlist[i] + ".jpg' />\
                      <input type=checkbox id='BOitem_" + itemlist[i] + "'>\
                      <span id='BOitemSpan_" + itemlist[i] + "'>" + unsafeWindow.ksoItems[itemlist[i]].count + "</span>&nbsp;";
      }
      
      m += "<tr align=center><td colspan=4>Knight : <SELECT id='RAApiKnight' type=list></select></td></tr>\
            <tr align=center><td colspan=4 ><INPUT type=checkbox id=ptmarch_autoknight " + (Options.marchAutoKnight ? 'CHECKED' : '') + " /> Auto select knight</td></tr>\
            <tr align=center><td colspan=4 style='vertical-align:middle'>" + BOitems + "</td></tr>\
            </table>\
            <DIV class=pbStat>Throne Configuration</div>";
      m += '<table>';
      m += '<tr>';
      m += '<td>March Size Boost : <span id=marchSizeBoost>' + throneEffectBonus(66) + '</span>%</td>';
      m += '<td>March Speed Boost : <span id=marchSpeedBoost>' + throneEffectBonus(67) + '</span>%</td>';
      m += '<td>Reinforce Boost : <span id=marchReinforceBoost>' + throneEffectBonus(69) + '</span>%</td>';
      m += '<td>Reassign Boost : <span id=marchReassignBoost>' + throneEffectBonus(71) + '</span>%</td>';
      m += '</tr>';
      m += '</table>';
      m += "<DIV class=pbStat>Saved Unit Configuration</div>\
            <TABLE>\
            <tr>\
            <td colspan=2><select id=pbFavouriteSelection></select><input type=button value='Delete' id=pbMarchDeleteFavourite><input type=button value='Delete All' id=pbMarchDeleteAllFavourites></td>\
            <td colspan=2>New : <input type=type id=pbMarchFavouriteName size=10 maxlength=12>&nbsp;<input type=button value='Save Troops' id=pbMarchSaveFavourite></td>\
            </tr>\
            <tr>\
            </table>\
            <DIV class=pbStat>March Status</div>\
            <table>\
            </tr>\
            <tr>\
            <td><div id=ptRAAStatus style='overflow-y:auto; max-height:50px; height: 50px;'>Waiting for Request ...</div></td>\
            </tr>\
            </table>";

      t.myDiv.innerHTML = m; 
      
      function populateFavourite() 
      {
        var options = "";
        
        options += "<option value=''>...</option>";

        for (var m in Options.marchFavourite) 
        {
          options += "<option value='" + m + "'>" + Options.marchFavourite[m][0] + "</option>";
        }  

        jQuery('#pbFavouriteSelection').html(options);
      }
    
      jQuery('#RAApiKnight').attr('disabled', Options.marchAutoKnight);
      
      $("ptmarch_autoknight").addEventListener('click', function()
      {
        Options.marchAutoKnight = this.checked;

        $('RAApiKnight').selectedIndex = 0;
        
        jQuery('#RAApiKnight').attr('disabled', Options.marchAutoKnight);
        
        saveOptions();
      },false);
      
      $("pbMarchDeleteAllFavourites").addEventListener ('click', function() 
      {
        Options.marchFavourite = {};
        saveOptions(); 
        populateFavourite();
      }, false); 
     
      $("pbMarchDeleteFavourite").addEventListener ('click', function() 
      {
        numfav = $("pbFavouriteSelection").value;
        
        if (numfav != "") 
        {
          Options.marchFavourite[numfav] = {};
          delete Options.marchFavourite[numfav];
          //Options.marchFavourite=unset(Options.marchFavourite, numfav);
          saveOptions(); 
          populateFavourite();
        }
      }, false); 
    
      $("BO_RAZ_Units").addEventListener ('click', function() 
      {
        var r = 1;
        for(unit in unsafeWindow.unitcost)
        {
          $("RAAnbunit"+r).value = 0; 
          r++;
        }
      }, false); 
    
      $("pbMarchSaveFavourite").addEventListener ('click', function() 
      {
        if ($("pbMarchFavouriteName").value == "") 
        {
          alert("Please fill in a name!");
          return;
        }
        var a = $("pbMarchFavouriteName").value;
        Options.marchFavourite[a] = {};
        var lisf = Options.marchFavourite[a];
        
        lisf[0] = $("pbMarchFavouriteName").value;
        
        for (r = 1 ; r < 13 ; r++) 
        {
          lisf[r] = $("RAAnbunit" + r).value;
        }
        
        $("pbMarchFavouriteName").value = "";
        
        saveOptions(); 
        populateFavourite();
      }, false); 
    
      $("pbFavouriteSelection").addEventListener ('change', function() 
      {
        numfav = $("pbFavouriteSelection").value;
        
        if (numfav == "") 
        {
          var r = 1;
          for(unit in unsafeWindow.unitcost)
          {
            $("RAAnbunit" + r).value=0; 
            r++;
          }
        }
        else 
        {
          var lisf = Options.marchFavourite[numfav];
          
          for (var m in lisf) 
          {
            if(m > 0)
            {
              if ($("RAAnbunit"+m)) 
              {
                $("RAAnbunit"+m).value = lisf[m];
              }
            }
          }
        }
      }, false); 

      // Fin gestion des Favourite
      $("BOitem_55").addEventListener ('click', function() 
      {
        $("BOitem_57").checked = false;
        t.estimerRes();
      }, false);  
   
      $("BOitem_57").addEventListener ('click', function() 
      {
        $("BOitem_55").checked = false;
        t.estimerRes();
      }, false);
    
      t.statutRAA = $('ptRAAStatus');
      t.destinationCityX = $('RAAtypetrpx');
      t.destinationCityY = $('RAAtypetrpy');
      t.destinationCityX.value = Options.marchDestinationX;
      t.destinationCityY.value = Options.marchDestinationY;
      
      if ($('maparea_map').style.display != "none") 
      {
       t.destinationCityX.value = $('mapXCoor').value;
       t.destinationCityY.value = $('mapYCoor').value;
      }
      
      jQuery('#pbMarchAllianceList').change(function ()
      {
        t.SelectAllianceDestination();
      });
      
      t.actionREN = $('RENaction');
      t.actionRENB = $('RENBaction');
      t.actionREE = $('REEaction');
      t.actionRAA = $('RAAaction');
      t.actionRAR = $('RARaction');

      t.actionRCNL = $('RCNLaction');
      
      t.actionRCNL.disabled = true;
      
      t.actionREN.addEventListener ('click', function () { t.actionMarch(2, 0); }, false);
      t.actionRAA.addEventListener ('click',  function () { t.actionMarch(4, 0); }, false);
      t.actionRAR.addEventListener ('click',  function () { t.actionMarch(5, 0); }, false);
      t.actionRENB.addEventListener ('click',  function () { t.actionMarch(2 ,1); }, false);
      t.actionREE.addEventListener ('click',  function () { t.actionMarch(3, 0); }, false);
      t.actionRCNL.addEventListener ('click',  function () 
      { 
        t.actionRAA.disabled = false;
        t.actionRAR.disabled = false;
        t.actionREN.disabled = false;
        t.actionRENB.disabled = false;
        t.actionREE.disabled = false;
        t.actionRCNL.disabled = true;
      }, false);
      
      t.destinationCityX.addEventListener ('change', function () { t.estimerRes(); }, false);
      t.destinationCityY.addEventListener ('change', function () { t.estimerRes(); }, false);       
      
      var dcp0 = new CdispCityPicker ('pbSourceCityControl', $('pbSourceCity'), false, t.clickRAACitySourceSelect, Cities.byID[unsafeWindow.currentcityid].idx);
      
      t.estimerRes();

      populateFavourite();
      t.populateAllianceList();
      
      t.clickRAACitySourceSelect(t.sourceCity);
      
      var closestNum = t.getclosestcity();
      
      t.dcp1 = new CdispCityPicker ('pbDestinationCityControl', $('pbDestinationCity'), false, t.estimerRes, null).bindToXYboxes($("RAAtypetrpx"),$("RAAtypetrpy"));
    }
    
    t.displayTimer = setInterval(t.updateDisplay, 1 * 1000);
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateDisplay : function ()
  {
    var t = Tabs.March;
    
    jQuery('#marchSizeBoost').text(throneEffectBonus(66));
    jQuery('#marchSpeedBoost').text(throneEffectBonus(67));
    jQuery('#marchReinforceBoost').text(throneEffectBonus(69));
    jQuery('#marchReassignBoost').text(throneEffectBonus(71));
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getclosestcity : function ()
  {
    var t = Tabs.March;
    var x1 = parseInt(t.sourceCity.x);
    var x2 = parseInt(t.destinationCityX.value);
    var y1 = parseInt(t.sourceCity.y);
    var y2 = parseInt(t.destinationCityY.value);
    var dist = distance (x1, y1, x2, y2);
    var closestDist = 999999;
    var closestNum = 1;
   
    for (var c = 0; c < Cities.numCities ; c++)
    {
      var city = Cities.cities[c];
      var dist = distance(city.x, city.y, x2, y2);
      
      if(dist < closestDist) 
      {
       closestDist = dist;
       closestNum = c;
      }
    }

    return closestNum;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  actionMarch: function(marchType, includeFood) 
  {
    var t = Tabs.March;  
    var totalunit = 0;
    var aura1 = false;
    var aura2 = false;
    var errMsg = "";
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    var x = t.destinationCityX.value;
    var y = t.destinationCityY.value;
    var cityId = t.sourceCity.id;
    var knightId = $("RAApiKnight").value;
    
    if (marchType == 3 && $("RAAnbunit3").value == 0) 
    {
      $("RAAnbunit3").value = 1;
    }
    
    var r = 1;
    for(unit in unsafeWindow.unitcost)
    {
      if (marchType == 3 && r != 3) 
      {
        $("RAAnbunit" + r).value=0;
      }
      
      if (parseInt($("RAAnbunit" + r).value) > parseInt($("RAAdestunit" + r).value)) 
      {
        $("RAAnbunit" + r).style.backgroundColor = "red";
        return false;
      }
      
      totalunit = totalunit + parseInt($("RAAnbunit" + r).value);
      $("RAAnbunit" + r).style.backgroundColor = "";
      
      r++;
    }
    
    var l_elem = $("BOitem_931");
    if(l_elem && l_elem.checked && parseInt(Seed.items["i931"]) > 0)
    {         
      aura1 = true;  
    }
    
    var l_elem = $("BOitem_932");
    if(l_elem && l_elem.checked && parseInt(Seed.items["i932"]) > 0)
    {         
      aura2 = true;     
    }

    var maxTroops = getMarchSize(cityId, aura1, aura2); 

    if (isNaN (x) || x < 0 || x > 749)
    {
      errMsg += "X coordinates must be between 0 and 749<BR>"; 
    }
    
    if (isNaN (y) || y < 0 || y > 749)
    {
      errMsg += "Y coordinates must be between 0 and 749<br>";
    }
    
    if ((!Options.marchAutoKnight) && $("RAApiKnight").value == 0 && marchType == 4) 
    {
      logit("March: marchAutoKnight - " + Options.marchAutoKnight);
      errMsg += "No knight selected!<BR>"; 
    }

    if (totalunit == 0) 
    {
      errMsg += 'You have no available units!<BR>';
    }
    
    if (totalunit > maxTroops) 
    {
      errMsg += 'You can only send ' + maxTroops + ' units.<BR>';
    }

    if (errMsg != "") 
    {
      t.statutRAA.innerHTML = "<FONT COLOR=#550000>" + errMsg + "</font>";
      return;
    }
    
    t.SaveCoordsOptions(x, y);
    
    var iused = new Array();
    var itemlist = [55, 57, 931, 932];
    
    for(var i = 0 ; i < itemlist.length ; i++)
    {
      var l_elem = $("BOitem_" + itemlist[i]);
      if(l_elem && l_elem.checked && parseInt(Seed.items["i" + itemlist[i]]) > 0)
      {
        iused.push(itemlist[i]);       
      }      
    }
    var res=0;
    
    if (includeFood == 1) 
    {
      var i = 1;
      for(unit in unsafeWindow.unitcost)
      {
        res += parseInt(unsafeWindow.unitstats['unt' + i][5] * $("RAAnbunit" + i).value * (1 + (0.10 * Seed.tech.tch10)));
        i++;
      }
    }

    if(Options.marchAutoKnight)
    {
      var knt = getFreeKnight(cityId);
      
      if(knt.length > 0)
      {
        knightId = knt[0].ID;
      }
    }
    
    params.items = iused.join(","); 
    params.cid = cityId;
    params.type = marchType;
    params.xcoord = x;
    params.ycoord = y;
    params.kid = knightId;
    params.r1 = res; 
    params.r2 = 0; 
    params.r3 = 0; 
    params.r4 = 0; 
    params.gold = 0; 
    
    var i = 1;
    for(unit in unsafeWindow.unitcost)
    {
      params["u" + i] = 0; 
      i++;
    }
 
    if (marchType != 3) 
    {
      var i = 1;
      for(unit in unsafeWindow.unitcost)
      {
        params["u" + i] = jQuery("#RAAnbunit" + i).val(); 
        i++;
      }
    }
    else 
    {
      params.u3 = $("RAAnbunit3").value;
    }

    t.actionRCNL.disabled = false;
    t.actionRAA.disabled = true;
    t.actionREN.disabled = true;
    t.actionRAR.disabled = true;
    t.actionRENB.disabled = true;
    t.actionREE.disabled = true;
    t.statutRAA.innerHTML = "<i><b>Sending march....</b></i>";
    
    var now = unixTime();
    if(RefreshEvery.NextRefresh < (now + (2 * 60)))
    {
      logit("March: extend refresh interval");
      RefreshEvery.delay(5 * 60);
    }

    
    t.doMarch(params, t.marchSent, t.marchFailure);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  marchFailure : function()
  {
    var t = Tabs.March;
    
    t.statutRAA.innerHTML = "<font color=red size='3px'><b>Error communicating with server!<b></font>";
    t.actionRAA.disabled = false;
    t.actionRAR.disabled = false;
    t.actionREN.disabled = false;
    t.actionRENB.disabled = false;
    t.actionREE.disabled = false;
    t.actionCNL.disabled = true;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  marchSent : function(params, result)
  {
    var t = Tabs.March;
    
    if (result.ok) 
    {
      var marchType = "";
      
      switch (params.type)
      {
        case 2:
          marchType = "Reinforce successful";
          break;
          
        case 3:
          marchType = "Scout successful";
          break;
          
        case 4:
          marchType = "Attack successful";
          break;
          
        case 5:
          marchType = "Reassign successful";
          break;
          
        default:
          marchType = "March successful";
          break;
      }
      
      t.statutRAA.innerHTML = "<center><font size='3px'><b>" + marchType + "</b></font></center>";
      t.clickRAACitySourceSelect(t.sourceCity);
    } 
    else 
    {
      t.statutRAA.innerHTML = "<font color=red size='3px'><b>Error sending march!<b></font>";
      
      if (result.msg) 
      {
        t.statutRAA.innerHTML += "<br><font color=black size='2px'>" + result.msg +"</font>";
      }
      else
      {
        logit("March: unknown error - " + JSON2.stringify(result, null, 2));
      }
    }
    
    t.actionRAA.disabled = false;
    t.actionRAR.disabled = false;
    t.actionREN.disabled = false;
    t.actionRENB.disabled = false;
    t.actionREE.disabled = false;
    t.actionCNL.disabled = true;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doMarch: function(params, notify, failure)
  {
    var _ajaxCall = function()
    {
      var profiler = new CM.Profiler("ResponseTime", "march.php");
      
      new PriorityAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
        fastMarch: true,
        
        onSuccess: function (transport) 
        {
          profiler.stop();
          var rslt = eval("(" + transport.responseText + ")");
          
          if (rslt.ok) 
          {
            addOutgoingMarch(params, rslt);

            var itemsUsed = params.items.split(","); 

            for(var i = 0 ; i < itemsUsed.length ; i++)
            {
              if(itemsUsed[i] == "")
              {
                continue;
              }
              
              Seed.items["i" + itemsUsed[i]] = parseInt(Seed.items["i" + itemsUsed[i]]) - 1;
              unsafeWindow.ksoItems[itemsUsed[i]].subtract();
            }
            
            CheckUpdateSeed(rslt);
          }
          else
          {
            if (rslt.user_action) 
            {
              var user_action = 
              {
                marchWarning: function() 
                {
                  logit('Captcha: [march] captcha warning');
                  actionLog('Captcha: [march] captcha warning');
                },
                marchCaptcha: function() 
                {
                  actionLog('Captcha: [march] triggered captcha');
                  logit('Captcha: [march] triggered captcha');
                  startCaptcha();
                },
                backOffWaitTime: function() 
                {
                  logit('Captcha: [march] back off time - ' + rslt.wait_time);
                  actionLog('Captcha: [march] back off time - ' + rslt.wait_time);
                  params.tt = rslt.tt;
                  setTimeout(_ajaxCall, rslt.wait_time * 1000)
                }
              };
              user_action[rslt.user_action].call();
            }
          }
          
          if(notify != null)
          {
            notify(params, rslt);
          }
        },
        
        onFailure: function () 
        {
          profiler.stop();
          if(failure != null)
          {
            failure();
          }
        }
      });
    };
    
    _ajaxCall();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  estimerRes: function() 
  {
    var t = Tabs.March;
    // CAlcul de ETA = Estimation du temps de marches
    var x1 = parseInt(t.sourceCity.x);
    var x2 = parseInt(t.destinationCityX.value);
    var y1 = parseInt(t.sourceCity.y);
    var y2 = parseInt(t.destinationCityY.value);
    var dist = distance (x1, y1, x2, y2);
    
    $("BOEstimationD").innerHTML = '<b>' + dist + '</b>&nbsp;<a href="javascript:void(0)" onclick="cm.utils.CoordinateLinkController.onClick(event)" class="coordinateLink">('+ t.destinationCityX.value +','+ t.destinationCityY.value +')</a>';     
     
    var r = 1;

    for(unit in unsafeWindow.unitcost)
    {
      var m = estETA(dist, r, t.sourceCity.id);
      
      $("BOEstimationTT" + r).innerHTML = m.etaStr;
      $("BOEstimationTZ" + r).innerHTML = m.friendEtaStr;
    
      r++;
    }
    
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  SelectAllianceDestination: function() 
  {
    var t = Tabs.March;

    var selection = jQuery('#pbMarchAllianceList').val();

    if (selection != '') 
    {
      var x = selection.substr(0, selection.lastIndexOf(','));
      var y = selection.substr(selection.lastIndexOf(',') + 1, selection.length);
      
      t.destinationCityX.value = x;
      t.destinationCityY.value = y;
    }
    
    t.estimerRes();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getAllianceMembersList : function() 
  {
    var t = Tabs.March;
    var myA = getMyAlliance();
    
    if (myA[0] != 0) 
    {
      var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
      params.perPage = 100;
      params.allianceId = myA[0];
      params.type = 'might';
      params.page = 1;
      
      new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getUserLeaderboard.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        
        onSuccess: function (rslt) 
        {
          if (rslt.ok)
          {
            //logit("Alliance: read alliance list");
            //logit("Alliance: - " + JSON2.stringify(rslt,null,2));
            Options.allianceList = rslt.results;
            saveOptions();
            t.populateAllianceList();
          }
          else
          {
            logit("Alliance: error reading alliance list [not OK]");
          }
        },
        
        onFailure: function (rslt) 
        {
          logit("Alliance: error reading alliance list [comms]");
        },
      });
    } 
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  populateAllianceList: function()
  {
    if(!Options.allianceList || Options.allianceList.length == 0)
    {
      return;
    }
    
    var m = "";
    
    for (var i = 0 ; i < Options.allianceList.length ; i++)
    {
      player = Options.allianceList[i];
      
      if (player.userId != 0)
      {
        for (var c = 0 ; c < player.cities.length ; c++)
        {
          var city = player.cities[c];
          
          if (Seed.player.name != player.displayName) 
          {
            m += "<option value='" + city.xCoord + ","+ city.yCoord + "'>" + player.displayName + " - City " + (c + 1) + " - " + city.xCoord + "," + city.yCoord+"</option>";
          }
        }
      }
    }
    
    jQuery('#pbMarchAllianceList').html("<option value=''>Selection...</option>" + m);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  SaveCoordsOptions: function(x , y) 
  {
    Options.marchDestinationX = x;
    Options.marchDestinationY = y;
    saveOptions ();
  },
   
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  clickRAACitySourceSelect : function (city)
  {
    var t = Tabs.March;
    
    if (t.sourceCity != city) 
    {
      t.sourceCity = city; 
    }
    
    var cityID = 'city'+ t.sourceCity.id;
    
    var r = 1;
    for(unit in unsafeWindow.unitcost)
    {   
      jQuery('#RAAdestunit' + r).val(parseInt(Seed.units[cityID]['unt'+r]));
      r++;
    }
    

    var knt = getFreeKnight(t.sourceCity.id);
    
    $('RAApiKnight').options.length = 0;
    var o = document.createElement("option");
    o.text = "--Select a Knight--"
    o.value = 0;
    $("RAApiKnight").options.add(o);
    
    if(!Options.marchAutoKnight)
    {
      for (k in knt)
      {
        if (knt[k]["Name"] != undefined)
        {
          var o = document.createElement("option");
          o.text = (knt[k]["Name"] + ' (' + knt[k]["Combat"] +')')
          o.value = knt[k]["ID"];
          $("RAApiKnight").options.add(o);
        }
      }
    }

    var itemlist=[55, 57, 931, 932];
    for(var i = 0 ; i < itemlist.length ; i++)
    {
      $('BOitemSpan_' + itemlist[i]).innerHTML = unsafeWindow.ksoItems[itemlist[i]].count;
    }

    var r = 1;
    for(unit in unsafeWindow.unitcost)
    {
      $("RAApdestunit" + r).addEventListener ('click', function() 
      {
        var nomcha = this.id.replace("RAApdest","RAAdest");
        var nomcha2 = this.id.replace("RAApdestunit","RAAnbunit");
        $(nomcha2).value=0; 
        
        var aura1 = false;
        var aura2 = false;
        
        var l_elem = $("BOitem_931");
        if(l_elem && l_elem.checked&&parseInt(Seed.items["i931"]) > 0)
        {         
          aura1 = true;  
        }
        
        var l_elem = $("BOitem_932");
        if(l_elem && l_elem.checked && parseInt(Seed.items["i932"]) > 0)
        {         
          aura2 = true;     
        }

        maxTroops = getMarchSize(t.sourceCity.id, aura1, aura2); 
        
        var nbunitto=0;
        
        for (r = 1 ; r < 13 ; r++) 
        {
          nbunitto += parseInt($("RAAnbunit" + r).value);
        }
        
        var libre = parseInt(maxTroops - nbunitto);
        
        if ($(nomcha).value >= libre) 
        {
           $(nomcha2).value = libre;
        }  
        else 
        {
           $(nomcha2).value = $(nomcha).value;
        }
      }, false);
      
      r++;
    }
    
    if (t.sourceCity != city) 
    {
      var r = 1;
      for(unit in unsafeWindow.unitcost)
      {
        $("RAAnbunit" + r).value="0";
        r++;
      }
    } 
    else 
    {
      var r = 1;
      for(unit in unsafeWindow.unitcost)
      {
        if ($("RAAnbunit" + r).value=="") 
          $("RAAnbunit" + r).value="0";
        
        if ($("RAAdestunit" + r).value=="") 
          $("RAAdestunit" + r).value="0";
        
        if (parseInt($("RAAnbunit" + r).value) > parseInt($("RAAdestunit"+r).value)) 
        {
          $("RAAnbunit" + r).value="0";
        }
        r++;
      }
    }
    
    t.estimerRes();
    var closestNum = t.getclosestcity();
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getFreeKnight(cityId)
{
  if(cityId.toString().substring(0,4) != "city")
  {
    logit("Debug: cityId not starting with 'city' - " + cityId );
    cityId = "city" + cityId;
  }

  knt = [];
  
  for (k in Seed.knights[cityId])
  {
    if (Seed.knights[cityId][k]["knightStatus"] == 1 && 
      Seed.leaders[cityId]["resourcefulnessKnightId"] != Seed.knights[cityId][k]["knightId"] && 
      Seed.leaders[cityId]["politicsKnightId"] != Seed.knights[cityId][k]["knightId"] && 
      Seed.leaders[cityId]["combatKnightId"] != Seed.knights[cityId][k]["knightId"] && 
      Seed.leaders[cityId]["intelligenceKnightId"] != Seed.knights[cityId][k]["knightId"])
    {
      knt.push ({
        Name:   Seed.knights[cityId][k]["knightName"],
        Combat: Seed.knights[cityId][k]["combat"],
        ID: Seed.knights[cityId][k]["knightId"],
      });
    }
  }
  
  knt = knt.sort(function sort(a , b) 
  {
    a = parseInt(a['Combat']);
    b = parseInt(b['Combat']);
    
    return a == b ? 0 : (a > b ? -1 : 1);
  });
  
  return knt;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getMarchSize(cityId, aura1, aura2)
{
  var marchSizeBoost = 1;
  var ut = unsafeWindow.unixtime();

  aura1 = aura1 || false;
  aura2 = aura2 || false;
  
  if(Seed.playerEffects.auras2Expire)
  {
    if(Seed.playerEffects.auras2Expire > ut)
    {
      marchSizeBoost = 1.3
    }
  }
  else if(Seed.playerEffects.aurasExpire)
  {
    if(Seed.playerEffects.aurasExpire > ut)
    {
      marchSizeBoost = 1.15
    }
  }

  if(aura2)
  {         
    marchSizeBoost += 0.5;     
  }
  else if(aura1)
  {         
    marchSizeBoost += 0.25;  
  }

  marchSizeBoost += (+throneEffectBonus(66) * 0.01);
  
  var maxTroops = getMaxMarchSize(cityId);
  
  maxTroops = maxTroops * marchSizeBoost;
  
  return maxTroops;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function estETA(dist, unit, cityID) 
{
  var ret= { ETA:0, etaStr:'N/D', friendETA:0, friendEtaStr:'N/D'};    
  
  if (dist <= 0) 
    return ret;
  
  var troop_type = unit;
  var horse = 0;
  
  if(troop_type > 6) 
    horse = 1;
  
  var troop_speed=parseInt(unsafeWindow.unitstats["unt"+troop_type][3]) * (1 + 0.1 * parseInt(Seed.tech.tch11));
  
  if (horse)
  {
    troop_speed = troop_speed * (1 + 0.05 * parseInt(Seed.tech.tch12))
  } 
  
  var Speed = troop_speed;
  var gi = unsafeWindow.cm.guardianModalModel.getMarchBonus();
  var tbms = (+throneEffectBonus(67) * 0.01);
  var multiplier = 1 + (gi * 0.01) + tbms;
  
  Speed = Speed * multiplier;
  
  var gSpeed = 0;
  var estSec;
  
  if (Speed > 0) 
  {
    gSpeed = Speed / 6000;
    estSec = Math.ceil(parseFloat(dist) / gSpeed);
  }
  var e=1;
  
  if ($("BOitem_55")) 
  {
    var l_elem = $("BOitem_55");
    
    if(l_elem && l_elem.checked > 0)
    { 
      e = 0.75;     
    }
  }
  
  if ($("BOitem_57")) 
  {
    var l_elem = $("BOitem_57");
    
    if(l_elem && l_elem.checked)
    {   
      e = 0.5;   
    }
  }
  
  ret.ETA = (parseInt((estSec * e + '')) + 30); 
  
  if(Seed.playerEffects.returnExpire > unsafeWindow.unixtime())
  {
    ret.ETA = parseInt(ret.ETA * 0.5);
  }
  
  ret.etaStr = timestr (ret.ETA, 1);
  var building = getCityBuilding (cityID, CM.BUILDING_TYPES.RELIEF_STATION);
  
  var tbris = (+throneEffectBonus(69) * 0.01);

  if (building) 
  {
    fSpeed = Speed * (1 + (parseInt(building.maxLevel) / 2) + tbris);
    gSpeed = fSpeed / 6000;
    estSec = (dist / gSpeed).toFixed(0);
    ret.friendETA = parseInt((estSec * e + '')) + 30; 
    ret.friendEtaStr = timestr ((ret.friendETA + ''), 1);
  }
  
  return ret;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab : transport
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.transport = {
  tabOrder: 101,
  tabLabel: 'Transport',
  myDiv: null,
  timer: null,
  traderState: [],
  lTR: [],
  tradeRoutes: [],
  checkdotradetimeout: null,
  count:0,
  check:false,

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init: function(div)
  {
    var t = Tabs.transport;
    t.myDiv = div;
    t.traderState = {running: false,};
    t.readTraderState();
    t.readTradeRoutes();
    t.timer = setTimeout(function(){ t.e_tradeRoutes(); }, 2 * 60 * 1000);

    var m = '<DIV id=pbTowrtDivF class=pbStat>'+translate("AUTOMATED TRANSPORT FUNCTION")+'</div><TABLE id=pbtraderfunctions width=100% height=0% class=pbTab><TR align="center">';
    if (t.traderState.running == false) {
        m += '<TD><INPUT id=pbTraderState type=submit value="Transport = OFF"></td>';
    } else {
        m += '<TD><INPUT id=pbTraderState type=submit value="Transport = ON"></td>';
    }
    m += '<TD><INPUT id=pbShowRoutes type=submit value="'+translate("Show Routes")+'"></td>';
    m += '</tr></table></div>';
    m += '<DIV class=pbStat>'+translate("TRADE ROUTE OPTIONS")+'</div>';
    m += '<TABLE id=pbtraderfunctions width=100% height=0% class=pbTab><TR align="center"><TR align="left">';
    m += '<TD colspan=4>'+translate("Time inbetween to check transport:")+' <INPUT id=pbtransportinterval type=text size=2 value="'+Options.transportinterval+'"\> '+translate("minutes")+'</td></tr></table>';
    m += '<TD colspan=4>'+translate("Dont send transport out if less then")+' <INPUT id=pbminwagons type=text size=8 value="'+Options.minwagons+'"\> '+translate("troops are needed. (Needless transports are skipped this way)")+'</td></tr></table>';
    m += '<DIV style="margin-top:10px;margin-bottom:5px;">'+translate("If the \"trade\" amount is 0 then it will transport the max amount above \"keep\". Gold only if there is space left...")+'</div></table>';
  
    
    m += '<DIV class=pbStat>'+translate("TRANSPORTS")+'</div>'; 
    m += '<TABLE id=pbaddtraderoute width=95% height=0% class=pbTab><TR align="left">';
    m += '<TD>'+translate("From City:")+'</td> <TD width=310px><DIV style="margin-bottom:10px;"><span id=ptrescity></span></div></td>';
    m += '</tr>';

    m += '<TR align="left">';
    m += '<TD>'+translate("To City:")+'</td> <TD width=310px><DIV style="margin-bottom:10px;"><span id=ptcityTo></span></div></td>';
    m += '<TD> or X:<INPUT id=ptcityX type=text size=3\> Y:<INPUT id=ptcityY type=text size=3\>';
    m += '<br> or <select id=pbTransportAllianceList><option value="">Selection...</option></select></td>';
    m += '</tr>';
    m += '<TABLE id=pbaddtraderoute height=0% class=pbTab><TR align="left">';
    m += '<TD width=75px>TroopType:</td><TD width=150px><SELECT id="TransportTroop">';
    
    for (y in unsafeWindow.unitcost) 
      m+='<option value="'+y+'">'+unsafeWindow.unitcost[y][0]+'</option>';
    
    m+='</select></td><TD width=75px>'+translate("Troops Available:")+'&nbsp;</td><TD id=TroopAmount align=left width=75px></td>';
    m+='<TD width=75px>'+translate("Global Carry Amount:")+'&nbsp;</td><TD id=CarryAmount align=left width=75px></td>';
    m += '<TR><TD >'+translate("Troops:")+' </td><TD><INPUT id=TroopsToSend type=text size=6 maxlength=6 value="0">&nbsp;&nbsp;<INPUT id=MaxTroops type=submit value="Max"></td>';
    m += '<TD width=50px><INPUT id=FillInMax type=submit value="<----"></td>';
    m +='<TD id=Calc colspan=3></td></tr>';
    m += '<TABLE id=pbaddtraderoute height=0% class=pbTab><TR align="center">';
    m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/food_30.png"></td>';
    m += '<TD id=TransRec1 align=right width=110px></td>';
    m += '<TD id=HaveRec1 align=right width=110px></td>';
    m += '<TD width=55px align=right><INPUT id=pbshipFood type=checkbox unchecked=true\></td>';
    m += '<TD width=180px  align=left>'+translate("Keep:")+' <INPUT id=pbtargetamountFood type=text size=11 maxlength=20 value="0" disabled=true\></td>';
    m += '<TD width=100px>'+translate("Trade:")+' <INPUT id=pbtradeamountFood type=text size=11 maxlength=20 value="0"\></td>';
    m += '<TD width=50px><INPUT id=MaxFood type=submit value="Max"></td></tr>';
    m += '<TR align="center">';
    m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/wood_30.png"></td>';
    m += '<TD id=TransRec2 align=right width=110px></td>';
    m += '<TD id=HaveRec2 align=right width=110px></td>';
    m += '<TD width=55px align=right><INPUT id=pbshipWood type=checkbox unchecked=true\></td>';
    m += '<TD width=180px align=left>'+translate("Keep:")+' <INPUT id=pbtargetamountWood type=text size=11 maxlength=20 value="0" disabled=true\></td>';
    m += '<TD width=100px>'+translate("Trade:")+' <INPUT id=pbtradeamountWood type=text size=11 maxlength=20 value="0"\></td>';
    m += '<TD width=50px><INPUT id=MaxWood type=submit value="Max"></td></tr>';
    m += '<TR align="center">';
    m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/stone_30.png"></td>';
    m += '<TD id=TransRec3 align=right width=110px></td>';
    m += '<TD id=HaveRec3 align=right width=110px></td>';
    m += '<TD width=55px align=right><INPUT id=pbshipStone type=checkbox unchecked=true\></td>';
    m += '<TD width=180px align=left>'+translate("Keep:")+' <INPUT id=pbtargetamountStone type=text size=11 maxlength=20 value="0" disabled=true\></td>';
    m += '<TD width=100px>'+translate("Trade:")+' <INPUT id=pbtradeamountStone type=text size=11 maxlength=20 value="0"\></td>';
    m += '<TD width=50px><INPUT id=MaxStone type=submit value="Max"></td></tr>';
    m += '<TR align="center">';
    m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/iron_30.png"></td>';
    m += '<TD id=TransRec4 align=right width=110px></td>';
    m += '<TD id=HaveRec4 align=right width=110px></td>';
    m += '<TD width=55px align=right><INPUT id=pbshipOre type=checkbox unchecked=true\></td>';
    m += '<TD width=180px align=left>'+translate("Keep:")+' <INPUT id=pbtargetamountOre type=text size=11 maxlength=20 value="0" disabled=true\></td>';
    m += '<TD width=100px>'+translate("Trade:")+' <INPUT id=pbtradeamountOre type=text size=11 maxlength=20 value="0"\></td>';
    m += '<TD width=50px><INPUT id=MaxOre type=submit value="Max"></td></tr>';
    m += '<TR align="center">';
    m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/aetherstone_30.png"></td>';
    m += '<TD id=TransRec5 align=right width=110px></td>';
    m += '<TD id=HaveRec5 align=right width=110px></td>';
    m += '<TD width=55px align=right><INPUT id=pbshipAstone type=checkbox unchecked=true\></td>';
    m += '<TD width=180px align=left>'+translate("Keep:")+' <INPUT id=pbtargetamountAstone type=text size=11 maxlength=20 value="0" disabled=true\></td>';
    m += '<TD width=100px>'+translate("Trade:")+' <INPUT id=pbtradeamountAstone type=text size=11 maxlength=20 value="0"\></td>';
    m += '<TD width=50px><INPUT id=MaxAstone type=submit value="Max"></td></tr>';
    m += '<TR align="center">';
    m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/gold_30.png"></td>';
    m += '<TD id=TransGold align=right width=110px></td>';
    m += '<TD id=HaveGold align=right width=110px></td>';
    m += '<TD width=55px align=right><INPUT id=pbshipGold type=checkbox unchecked=true\></td>';
    m += '<TD width=180px align=left>'+translate("Keep:")+' <INPUT id=pbtargetamountGold type=text size=11 maxlength=20 value="0" disabled=true\></td>';
    m += '<TD width=100px>'+translate("Trade:")+' <INPUT id=pbtradeamountGold type=text size=11 maxlength=20 value="0"\></td>';
    m += '<TD width=50px><INPUT id=MaxGold type=submit value="Max"></td></tr>';

    m += '</table>';

    m += '<DIV style="text-align:center; margin-top:15px"><INPUT id=pbSaveRoute type=submit value="'+translate("Add Route")+'"><INPUT id=pbManualSend type=submit value="'+translate("Manual Transport")+'"></div>';
    m += '<br/><DIV id=pbTraderDivDRoute class=pbStat>'+translate("Manual Transport Status")+'</div>';
    m += '<br/><DIV id=errorSpace>Waiting for manual request...</div><br/>'
    
    t.myDiv.innerHTML = m;
    
    document.getElementById('TransportTroop').value = 'unt9';
    
    t.tcp = new CdispCityPicker ('pttrader', document.getElementById('ptrescity'), true, t.updateResources, 0);
    t.tcpto = new CdispCityPicker ('pttraderTo', document.getElementById('ptcityTo'), true, t.clickCitySelect);
    t.tcpto.bindToXYboxes(document.getElementById ('ptcityX'), document.getElementById ('ptcityY'));
    
    jQuery('#pbTransportAllianceList').change(function ()
    {
      var selection = jQuery('#pbTransportAllianceList').val();

      if (selection != '') 
      {
        var x = selection.substr(0, selection.lastIndexOf(','));
        var y = selection.substr(selection.lastIndexOf(',') + 1, selection.length);
        
        $('ptcityX').value = x;
        $('ptcityY').value = y;
      }
    });

    document.getElementById('TransportTroop').addEventListener('change', function(){t.updateTroops();}, false);
    document.getElementById('pbTraderState').addEventListener('click', function(){t.toggleTraderState(this);}, false);
    document.getElementById('pbSaveRoute').addEventListener('click', function(){t.addTradeRoute();}, false);
    document.getElementById('pbManualSend').addEventListener('click', function(){t.ManualTransport();}, false);
    document.getElementById('pbShowRoutes').addEventListener('click', function(){t.showTradeRoutes();}, false);
    document.getElementById('FillInMax').addEventListener('click', function(){document.getElementById('TroopsToSend').value = t.TroopsNeeded;}, false);
    
    document.getElementById('MaxTroops').addEventListener('click', function()
    {
      var max = t.Troops;

      maxTroops = getMarchSize('city' + t.tcp.city.id);
      
      if ( t.Troops > maxTroops ) 
        max = maxTroops;
      
      document.getElementById('TroopsToSend').value = max;
    }, false);
    document.getElementById('MaxFood').addEventListener('click', function(){
      t.Food = 0;
      var input = t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone);
      document.getElementById('pbtradeamountFood').value = (parseInt(input) <= parseIntCommas(document.getElementById('TransRec1').innerHTML))?input:parseIntCommas(document.getElementById('TransRec1').innerHTML);
    }, false);
    document.getElementById('MaxWood').addEventListener('click', function(){
      t.Wood = 0;
      var input = t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone);
      document.getElementById('pbtradeamountWood').value = (parseInt(input) <= parseIntCommas(document.getElementById('TransRec2').innerHTML))?input:parseIntCommas(document.getElementById('TransRec2').innerHTML);
    }, false);
    document.getElementById('MaxStone').addEventListener('click', function(){
      t.Stone = 0;
      var input = t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone);
      document.getElementById('pbtradeamountStone').value = (parseInt(input) <= parseIntCommas(document.getElementById('TransRec3').innerHTML))?input:parseIntCommas(document.getElementById('TransRec3').innerHTML);
    }, false);
    document.getElementById('MaxOre').addEventListener('click', function(){
      t.Ore = 0;
      var input = t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone);
      document.getElementById('pbtradeamountOre').value = (parseInt(input) <= parseIntCommas(document.getElementById('TransRec4').innerHTML))?input:parseIntCommas(document.getElementById('TransRec4').innerHTML);
    }, false);
    
    $('MaxGold').addEventListener('click', function(){
      t.Gold = 0;
      var input = t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone);
      document.getElementById('pbtradeamountGold').value = (parseInt(input) <= parseIntCommas(document.getElementById('TransGold').innerHTML))?input:parseIntCommas(document.getElementById('TransGold').innerHTML);
    }, false);
    
    $('MaxAstone').addEventListener('click', function(){
      t.Astone = 0;
      var input = t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone);
      document.getElementById('pbtradeamountAstone').value = (parseInt(input) <= parseIntCommas(document.getElementById('TransRec5').innerHTML))?input:parseIntCommas(document.getElementById('TransRec5').innerHTML);
    }, false);
    
    $('pbtransportinterval').addEventListener('keyup', function(){
      if (isNaN(document.getElementById('pbtransportinterval').value)){ document.getElementById('pbtransportinterval').value=60 ;}
      Options.transportinterval = document.getElementById('pbtransportinterval').value;
      saveOptions();
    }, false);
    
    jQuery('[id^=pbtargetamount]').keyup(function ()
    {
      this.value = this.value.replace(/[^0-9\.]/g,'');
    });

    jQuery('[id^=pbtradeamount]').keyup(function ()
    {
      this.value = this.value.replace(/[^0-9\.]/g,'');
    });

    jQuery('#pbminwagons').keyup(function ()
    {
      this.value = this.value.replace(/[^0-9\.]/g,'');
      Options.minwagons = parseInt(this.value);
      saveOptions();
    }, false)
    
    jQuery('[id^=pbship]').click(function ()
    {
      var resource = this.id.substr(6);
      jQuery('#pbtargetamount' + resource).attr("disabled", !this.checked)
    });
    
    window.addEventListener('unload', t.onUnload, false);

    t.populateAllianceList();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  populateAllianceList: function()
  {
    logit("Alliance: populate alliance list");
    if(!Options.allianceList || Options.allianceList.length == 0)
    {
      logit("Alliance: no alliance list data");
      return;
    }
    
    var m = "";
    
    for (var i = 0 ; i < Options.allianceList.length ; i++)
    {
      player = Options.allianceList[i];
      
      if (player.userId != 0)
      {
        for (var c = 0 ; c < player.cities.length ; c++)
        {
          var city = player.cities[c];
          
          if (Seed.player.name != player.displayName) 
          {
            m += "<option value='" + city.xCoord + ","+ city.yCoord + "'>" + player.displayName + " - City " + (c + 1) + " - " + city.xCoord + "," + city.yCoord+"</option>";
          }
        }
      }
    }
    
    jQuery('#pbTransportAllianceList').html("<option value=''>Selection...</option>" + m);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateResources : function ()
  {
    var t = Tabs.transport;
    var ToCity = null;
    
    for (var i=1;i<=5;i++)
    {
      if(i==5)
        $('TransRec'+i).innerHTML = addCommas ( parseInt(Seed.resources["city" + t.tcp.city.id]['rec'+i][0]) );
      else
        $('TransRec'+i).innerHTML = addCommas ( parseInt(Seed.resources["city" + t.tcp.city.id]['rec'+i][0]/3600) );
    }
    
    $('TransGold').innerHTML = addCommas ( parseInt(Seed.citystats["city" + t.tcp.city.id]['gold'][0]) );
    
    for (ii in Seed.cities)
    {
      if (Seed.cities[ii][2] == $('ptcityX').value && Seed.cities[ii][3] == $('ptcityY').value)
      {
        ToCity = Seed.cities[ii][0];
      }
    }
    
    for (var i = 1 ; i <= 5 ; i++)
    {
      if (ToCity != null)
        if(i == 5)
          document.getElementById('HaveRec'+i).innerHTML = addCommas ( parseInt(Seed.resources["city" + ToCity]['rec'+i][0]) );
        else
          document.getElementById('HaveRec'+i).innerHTML = addCommas ( parseInt(Seed.resources["city" + ToCity]['rec'+i][0]/3600) );
      else 
        document.getElementById('HaveRec'+i).innerHTML = "----";
    }
    
    if (ToCity != null) 
      document.getElementById('HaveGold').innerHTML = addCommas ( parseInt(Seed.citystats["city" + ToCity]['gold'][0]) );
    else  
      document.getElementById('HaveGold').innerHTML =  "----";   
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateTroops : function (city)
  {
    var t = Tabs.transport;
    var fontcolor = 'black';
    
    t.Food = parseIntCommas(document.getElementById('pbtradeamountFood').value);
    t.Wood = parseIntCommas(document.getElementById('pbtradeamountWood').value);
    t.Stone = parseIntCommas(document.getElementById('pbtradeamountStone').value);
    t.Ore = parseIntCommas(document.getElementById('pbtradeamountOre').value);
    t.Gold = parseIntCommas(document.getElementById('pbtradeamountGold').value);
    t.Astone = parseIntCommas(document.getElementById('pbtradeamountAstone').value)*5;
    
    var unit = document.getElementById('TransportTroop').value;
    
    t.Troops = parseInt(Seed.units['city' + t.tcp.city.id][unit]);
    
    var featherweight = parseInt(Seed.tech.tch10);
    var throneBoost = (+throneEffectBonus(6));
    
    if (unsafeWindow.cm.unitFrontendType[unit] == "siege") 
    {
      throneBoost += (+throneEffectBonus(59));
    };

    if (unsafeWindow.cm.unitFrontendType[unit] == "horsed") 
    {
      throneBoost += (+throneEffectBonus(48));
    };

    // TODO : the above does not account for the max being broken due to cummulative boosts
    
    var Load = parseInt(unsafeWindow.unitstats[unit]['5']);
    var LoadUnit = Math.floor((1 + (throneBoost * 0.01) + (featherweight * 0.1)) * Load);
    var GlobalMaxLoad = t.Troops * LoadUnit;
    t.MaxLoad = parseInt(document.getElementById('TroopsToSend').value) * LoadUnit;
    t.TroopsNeeded = Math.ceil((t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone) / LoadUnit);
    t.TroopsNeeded = t.TroopsNeeded.toFixed(0); 
    
    if (t.TroopsNeeded < ((t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Astone) / LoadUnit)) 
      t.TroopsNeeded++; 
      
    if ( t.TroopsNeeded > t.Troops) 
      fontcolor = 'red';
    
    if (t.Troops > 0 ) 
      document.getElementById('TroopAmount').innerHTML = '<FONT color='+fontcolor+'>' + addCommas(t.Troops) + '</font>';
    else 
      document.getElementById('TroopAmount').innerHTML = 0;
    
    if (GlobalMaxLoad > 0) 
      document.getElementById('CarryAmount').innerHTML = addCommas(GlobalMaxLoad);
    else  
      document.getElementById('CarryAmount').innerHTML = 0;
    
    document.getElementById('Calc').innerHTML = ''+translate("Resources:")+' ' +  addCommas(t.Food + t.Wood + t.Stone + t.Ore + t.Gold  + t.Astone) + ' / ' + addCommas(t.MaxLoad) + '&nbsp;&nbsp;('+translate("Troops Needed:")+' <FONT color='+fontcolor+'>' + addCommas(t.TroopsNeeded) + '</font> )' ;
  },    
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getRallypoint : function(cityId)
  {
    var t = Tabs.transport;

    for (var o in Seed.buildings[cityId])
    {
      var buildingType = parseInt(Seed.buildings[cityId][o][0]);
      var buildingLevel = parseInt(Seed.buildings[cityId][o][1]);

      if (buildingType == 12)
      {
        return parseInt(buildingLevel);
        break;
      }
    }
    
    return 0;
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  e_tradeRoutes : function() 
  {
    var t = Tabs.transport;
    clearTimeout(t.timer);
    var now = new Date();
    
    if (t.traderState.running == true) 
    {
      var now = new Date().getTime()/1000.0;
      now = now.toFixed(0);
      var last = Options.lasttransport;
  
      if ( now > (parseInt(last) + (Options.transportinterval * 60))) 
      {
        t.checkdoTrades();
        Options.lasttransport = now;
        saveOptions();
      }
    }
    
    t.timer = setTimeout(function(){ t.e_tradeRoutes();}, 60 * 1000);
  },
      
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  delTradeRoutes: function() 
  {
    var t = Tabs.transport; 
    t.tradeRoutes= [];
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkcoords : function (obj)
  {
    var t = Tabs.transport;

    if(obj.id == 'pbok')
    {
      t.check = true;
      t.addTradeRoute();
    }

    return;     
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  addTradeRoute: function () 
  {
    var valid = true;
    var t = Tabs.transport;
    var city = t.tcp.city.id;
    
    if (document.getElementById('ptcityX').value==0 && document.getElementById('ptcityY').value ==0 && !t.check)
    {
      new CdialogConfirm ('<SPAN class=boldRed>'+translate("You are about to set a route to location 0,0!")+'</span>', t.checkcoords, unsafeWindow.modal_attack_check, mainPop.getMainDiv); 
      return;
    }
    
    var ship_Food = document.getElementById('pbshipFood').checked;
    var ship_Wood = document.getElementById('pbshipWood').checked;
    var ship_Stone = document.getElementById('pbshipStone').checked;
    var ship_Ore = document.getElementById('pbshipOre').checked;
    var ship_Astone = document.getElementById('pbshipAstone').checked;
    var ship_Gold = document.getElementById('pbshipGold').checked;
    var target_Food = parseIntCommas(document.getElementById('pbtargetamountFood').value);
    var target_Wood = parseIntCommas(document.getElementById('pbtargetamountWood').value);
    var target_Stone = parseIntCommas(document.getElementById('pbtargetamountStone').value);
    var target_Ore = parseIntCommas(document.getElementById('pbtargetamountOre').value);
    var target_Astone = parseIntCommas(document.getElementById('pbtargetamountAstone').value);
    var target_Gold = parseIntCommas(document.getElementById('pbtargetamountGold').value);
    var trade_Food = parseIntCommas(document.getElementById('pbtradeamountFood').value);
    var trade_Wood = parseIntCommas(document.getElementById('pbtradeamountWood').value);
    var trade_Stone = parseIntCommas(document.getElementById('pbtradeamountStone').value);
    var trade_Ore = parseIntCommas(document.getElementById('pbtradeamountOre').value);
    var trade_Astone = parseIntCommas(document.getElementById('pbtradeamountAstone').value);
    var trade_Gold = parseIntCommas(document.getElementById('pbtradeamountGold').value);
    var target_x = document.getElementById('ptcityX').value;
    var target_y = document.getElementById('ptcityY').value;
    var target_city = 0;
    var TroopType = document.getElementById('TransportTroop').value;
    var route_state = true;
    
    if(t.tcpto.city) 
    {
      if(t.tcpto.city.x == target_x && t.tcpto.city.y == target_y) 
      {
        target_city = t.tcpto.city.id;
      }
    }
      
    if (valid == true) 
    {
      var lTR = t.tradeRoutes;
      lTR.push({
        city:           city,
        ship_Food:      ship_Food,
        target_Food:    target_Food,
        trade_Food:     trade_Food,
        ship_Wood:      ship_Wood,
        target_Wood:    target_Wood,
        trade_Wood:     trade_Wood,
        ship_Stone:     ship_Stone,
        target_Stone:   target_Stone,
        trade_Stone:    trade_Stone,
        ship_Ore:       ship_Ore,
        target_Ore:     target_Ore,
        trade_Ore:      trade_Ore,
        ship_Astone:    ship_Astone,
        target_Astone:  target_Astone,
        trade_Astone:   trade_Astone,
        ship_Gold:      ship_Gold,
        target_Gold:    target_Gold,
        trade_Gold:     trade_Gold,
        target_x:       target_x,
        target_y:       target_y,
        target_city:    target_city,
        TroopType:      TroopType,
        route_state:    "true"
      });
    }
    
    document.getElementById('pbTraderDivDRoute').style.background ='#99FF99';
    
    setTimeout(function(){ (document.getElementById('pbTraderDivDRoute').style.background =''); }, 1000);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  showTradeRoutes: function () {
    var t = Tabs.transport;
    var popTradeRoutes = null;
    t.popTradeRoutes = new pbPopup('pbShowTrade', 0, 0, 750, 485, true, function() {clearTimeout (1000);});
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbTab" id="pbRoutesQueue">';       
    t.popTradeRoutes.getMainDiv().innerHTML = '</table></div>' + m;
    t.popTradeRoutes.getTopDiv().innerHTML = '<TD><CENTER><B>'+translate("Transport routes")+'</b></center></td>';
    t.paintTradeRoutes();
    t.popTradeRoutes.show(true) ;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paintTradeRoutes: function(){
    var t = Tabs.transport;
    var r = t.tradeRoutes;
    var cityname;
    var m= '<TABLE id=paintRoutes class=pbTab>'; 

    for (var i = 0 ; i < (r.length) ; i++) {
      var queueId = i;

      var cityname = (Cities.byID[r[queueId].city] ? Cities.byID[r[queueId].city].name : "null");
      var citynameTo = null, TO, status, unit;
      if(typeof r[queueId].target_city != 'undefined' && parseInt(r[queueId].target_city) > 0 && Cities.byID[r[queueId].target_city] != 'undefined')
      {
        citynameTo = (Cities.byID[r[queueId].target_city] ? Cities.byID[r[queueId].target_city].name : "null");      
      }
      else if (citynameTo == null) 
      {
        TO = r[i].target_x +','+ r[i].target_y;
      }
      else 
      { 
        TO = citynameTo;
      }
      
      if (r[i].route_state) {
        status = '<FONT color=green>'+translate("Enabled")+'</font>';
      } else {
        status = '<FONT color=red>'+translate("Disabled")+'</font>';
      }
      
      if (r[i].TroopType == undefined) {
        unit = 'unt9';
      } else {
        unit = r[i].TroopType;
      }
      
      m += '<TR><TD TD width=12px>&nbsp;&nbsp;</td></tr>';
      m +='<TR><TD width=20px>'+(i+1)+'</td><TD width=175px>'+translate("From:")+'&nbsp;&nbsp;'+ cityname +'</TD><TD width=175px>'+translate("To:")+'&nbsp;&nbsp;'+ TO +'</td><TD width=175px>'+status+'</td>';
      m +='<TD width=60px><A onclick="traceEdit('+queueId+')">'+translate("Edit")+'</a></td><TD width=60px><A onclick="traceDelete('+queueId+')">Delete</a></td></tr>';
      m += '<TR><TD></td><TD>Troops:&nbsp;&nbsp;'+unsafeWindow.unitcost[unit][0]+'</td></tr>';

      if (r[i].ship_Food) {
        m += '<TR><TD></td><TD align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/food_30.png"></td><TD>'+translate("Target:")+' '+ addCommas(r[i].target_Food) +'</td><TD>'+translate("Trade:")+' '+ addCommas(r[i].trade_Food)+'</td>';
      }
      
      if (r[i].ship_Wood) { 
        m += '<TR><TD></td><TD align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/wood_30.png"></td><TD>'+translate("Target:")+' '+ addCommas(r[i].target_Wood) +'</td><TD>'+translate("Trade:")+' '+ addCommas(r[i].trade_Wood)+'</td>';
      }
      
      if (r[i].ship_Stone) {
        m += '<TR><TD></td><TD align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/stone_30.png"></td><TD>'+translate("Target:")+' '+ addCommas(r[i].target_Stone) +'</td><TD>'+translate("Trade:")+' '+ addCommas(r[i].trade_Stone)+'</td>';
      }
      
      if (r[i].ship_Ore) {
        m += '<TR><TD></td><TD align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/iron_30.png"></td><TD>'+translate("Target:")+' '+ addCommas(r[i].target_Ore) +'</td><TD>'+translate("Trade:")+' '+ addCommas(r[i].trade_Ore)+'</td>';
      }
      
      if (r[i].ship_Astone) {
        m += '<TR><TD></td><TD align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/aetherstone_30.png"></td><TD>'+translate("Target:")+' '+ addCommas(r[i].target_Astone) +'</td><TD>'+translate("Trade:")+' '+ addCommas(r[i].trade_Astone)+'</td>';
      }
      if (r[i].ship_Gold) {
        m += '<TR><TD></td><TD align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/gold_30.png"></td><TD>'+translate("Target:")+' '+ addCommas(r[i].target_Gold) +'</td><TD>'+translate("Trade:")+' '+ addCommas(r[i].trade_Gold)+'</td>';
      }
    }
    m +='</table>';
    
    document.getElementById('pbRoutesQueue').innerHTML= m; 
    
    unsafeWindow.traceEdit = t.editQueueElement;
    unsafeWindow.traceDelete = t.cancelQueueElement;
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  cancelQueueElement: function(queueId)
  {
    var t = Tabs.transport;
    var queueId = parseInt(queueId);
    t.tradeRoutes.splice(queueId, 1);
    t.showTradeRoutes();
  },
   
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  editQueueElement: function(queueId){
    var t = Tabs.transport;
    var r = t.tradeRoutes;
    var queueId = parseInt(queueId);
    var cityname = Cities.byID[r[queueId].city].name;
    var citynameTo, TO;

    if(typeof r[queueId].target_city != 'undefined' || parseInt(r[queueId].target_city) > 0) {
      citynameTo = Cities.byID[r[queueId].target_city].name;
    }

    var Types = ['food','wood','stone','iron','aetherstone','gold'];

    if (citynameTo == null) {
      TO = r[queueId].target_x +','+ r[queueId].target_y;
    } else {
      TO = citynameTo; 
    }
    
    var n = '<TABLE id=editRoutes class=pbTab>';
    n +='<TD>'+translate("From:")+'&nbsp;'+ cityname +'</td><TD>'+translate("To:")+'&nbsp;'+ TO +'</td>';
    n +='<TD><INPUT id=TradeStatus type=checkbox>&nbsp;Enable Route</td>';
    n += '<TD width=150px>'+translate("Troop Type:")+'<SELECT id="pbbTransportTroop">';
    
    for (y in unsafeWindow.unitcost) {
      n+='<option value="'+y+'">'+unsafeWindow.unitcost[y][0]+'</option>';
    }
    
    n+='</select></td></table><BR><TABLE  id=editRoutes class=pbTab>';
    
    for (var i=0;i<Types.length;i++){
      var icon = Types[i];
       n += '<TR><TD width=50px align=center><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/'+icon+'_30.png"></td>';
       n += '<TD width=50px align=center><INPUT id=pbbship'+icon+' type=checkbox></td>';
       n += '<TD width=125px>'+translate("Keep:")+' <INPUT id=pbbtargetamount'+icon+' type=text size=11 maxlength=11 value="0"></td>';
       n += '<TD width=125px>'+translate("Trade:")+' <INPUT id=pbbtradeamount'+icon+' type=text size=11 maxlength=11 value="0"\></td></tr>';
    }
    
    n+='</table><BR><TABLE id=editRoutes class=pbTab><TR><TD><a class="button20" id="Cancel"><span>'+translate("Cancel")+'</span></a></td>';
    n+='<TD><a class="button20" id="Save"><span>'+translate("Save")+'</span></a></td></tr>';
    n +='</table>';
       
    document.getElementById('pbRoutesQueue').innerHTML= n;
    document.getElementById('TradeStatus').checked = r[queueId].route_state;

    var unit;
    
    if (r[queueId].TroopType == undefined) {
      unit = 'unt9';
    } else {
      unit = r[queueId].TroopType;
    }
    
    document.getElementById('pbbTransportTroop').value = unit;
    document.getElementById('pbbshipfood').checked = r[queueId].ship_Food;
    document.getElementById('pbbshipwood').checked = r[queueId].ship_Wood;
    document.getElementById('pbbshipstone').checked = r[queueId].ship_Stone;
    document.getElementById('pbbshipiron').checked = r[queueId].ship_Ore;
    document.getElementById('pbbshipaetherstone').checked = r[queueId].ship_Astone;
    document.getElementById('pbbshipgold').checked = r[queueId].ship_Gold;
    document.getElementById('pbbtargetamountfood').value = r[queueId].target_Food;
    document.getElementById('pbbtargetamountwood').value = r[queueId].target_Wood;
    document.getElementById('pbbtargetamountstone').value = r[queueId].target_Stone;
    document.getElementById('pbbtargetamountiron').value = r[queueId].target_Ore;
    document.getElementById('pbbtargetamountaetherstone').value = r[queueId].target_Astone;
    document.getElementById('pbbtargetamountgold').value = r[queueId].target_Gold;
    document.getElementById('pbbtradeamountfood').value = r[queueId].trade_Food;
    document.getElementById('pbbtradeamountwood').value = r[queueId].trade_Wood;
    document.getElementById('pbbtradeamountstone').value = r[queueId].trade_Stone;
    document.getElementById('pbbtradeamountiron').value = r[queueId].trade_Ore;
    document.getElementById('pbbtradeamountaetherstone').value = r[queueId].trade_Astone;
    document.getElementById('pbbtradeamountgold').value = r[queueId].trade_Gold;
    document.getElementById('Cancel').addEventListener('click', function(){t.showTradeRoutes();}, false);
    document.getElementById('Save').addEventListener('click', function(){
      r[queueId].route_state = document.getElementById('TradeStatus').checked;
      r[queueId].TroopType = document.getElementById('pbbTransportTroop').value;
      r[queueId].ship_Food = (document.getElementById('pbbshipfood').checked);
      r[queueId].ship_Wood = (document.getElementById('pbbshipwood').checked);
      r[queueId].ship_Stone = (document.getElementById('pbbshipstone').checked);
      r[queueId].ship_Ore = (document.getElementById('pbbshipiron').checked);
      r[queueId].ship_Astone = (document.getElementById('pbbshipaetherstone').checked);
      r[queueId].ship_Gold = (document.getElementById('pbbshipgold').checked);
      r[queueId].target_Food = parseIntCommas(document.getElementById('pbbtargetamountfood').value);
      r[queueId].target_Wood = parseIntCommas(document.getElementById('pbbtargetamountwood').value);
      r[queueId].target_Stone = parseIntCommas(document.getElementById('pbbtargetamountstone').value);
      r[queueId].target_Ore = parseIntCommas(document.getElementById('pbbtargetamountiron').value);
      r[queueId].target_Astone = parseIntCommas(document.getElementById('pbbtargetamountaetherstone').value);
      r[queueId].target_Gold = parseIntCommas(document.getElementById('pbbtargetamountgold').value);
      r[queueId].trade_Food = parseIntCommas(document.getElementById('pbbtradeamountfood').value);
      r[queueId].trade_Wood = parseIntCommas(document.getElementById('pbbtradeamountwood').value);
      r[queueId].trade_Stone = parseIntCommas(document.getElementById('pbbtradeamountstone').value);
      r[queueId].trade_Ore = parseIntCommas(document.getElementById('pbbtradeamountiron').value);
      r[queueId].trade_Astone = parseIntCommas(document.getElementById('pbbtradeamountaetherstone').value);
      r[queueId].trade_Gold = parseIntCommas(document.getElementById('pbbtradeamountgold').value);
      t.showTradeRoutes();
    }, false);
  },
     
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  saveTradeRoutes: function()
  {
    var t = Tabs.transport;
    var serverID = getServerId();
    GM_setValue('tradeRoutes_' + serverID, JSON2.stringify(t.tradeRoutes));
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  readTradeRoutes: function()
  {
    var t = Tabs.transport;
    var serverID = getServerId();
    s = GM_getValue('tradeRoutes_' + serverID);
    
    if (s != null) 
    {
      route = JSON2.parse(s);
      for (k in route)
        t.tradeRoutes[k] = route[k];
    }
    
    t.checkcitymoved();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkcitymoved: function(){
        var t = Tabs.transport;
    for(var i=0; i < t.tradeRoutes.length; i++){
      if(typeof t.tradeRoutes[i].target_city == 'undefined' || parseInt(t.tradeRoutes[i].target_city) == 0)
        continue;
      if(t.tradeRoutes[i].target_x != Cities.byID[t.tradeRoutes[i].target_city].x)
        t.tradeRoutes[i].target_x = Cities.byID[t.tradeRoutes[i].target_city].x;
      if(t.tradeRoutes[i].target_y != Cities.byID[t.tradeRoutes[i].target_city].y)
        t.tradeRoutes[i].target_y = Cities.byID[t.tradeRoutes[i].target_city].y;
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  saveTraderState: function()
  {
    var t = Tabs.transport;
        var serverID = getServerId();
        GM_setValue('traderState_' + serverID, JSON2.stringify(t.traderState));
    },
    readTraderState: function(){
        var t = Tabs.transport;
        var serverID = getServerId();
        s = GM_getValue('traderState_' + serverID);
        if (s != null) {
            state = JSON2.parse(s);
            for (k in state)
                t.traderState[k] = state[k];
        }
    },
    toggleTraderState: function(obj){
    var t = Tabs.transport;
        if (t.traderState.running == true) {
            t.traderState.running = false;
            obj.value = "Transport = OFF";
      clearTimeout(t.checkdotradetimeout);
      t.count = 0;
        }
        else {
            t.traderState.running = true;
            obj.value = "Transport = ON";
      t.e_tradeRoutes();
        }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkdoTrades: function()
  {
    var t = Tabs.transport;
    
    if(t.tradeRoutes.length==0) 
    return;
    
    t.doTrades(t.count);
    t.count++;
    
    if(t.count < t.tradeRoutes.length)
    {
      t.checkdotradetimeout = setTimeout(function() { t.checkdoTrades();}, 5000);
    } 
    else 
    {
      t.count = 0;
    }
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  doTrades: function(count)
  {
    var t = Tabs.transport;
    
    if(t.tradeRoutes.length==0) 
      return;
    
    if(!t.tradeRoutes[count]["route_state"]) 
      return;
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    params.gold =0;
    params.r1 =0;
    params.r2 =0;
    params.r3 =0;
    params.r4 =0 ;
    params.r5 =0 ;
    params.kid = 0;
    
    var carry_amount= 0;
    var wagons_needed=0;
    var citymax = 0;
    var city = t.tradeRoutes[count]["city"];
    var cityID = 'city' + city;
    
    if(!Cities.byID[city]) 
      return;
    
    var xcoord = t.tradeRoutes[count]["target_x"];
    var ycoord = t.tradeRoutes[count]["target_y"];

    var trade_Food = t.tradeRoutes[count]["trade_Food"];
    var trade_Wood = t.tradeRoutes[count]["trade_Wood"];
    var trade_Stone = t.tradeRoutes[count]["trade_Stone"];
    var trade_Ore = t.tradeRoutes[count]["trade_Ore"];
    var trade_Astone = t.tradeRoutes[count]["trade_Astone"];
    var trade_Gold = t.tradeRoutes[count]["trade_Gold"];

    var target_Food = t.tradeRoutes[count]["target_Food"];
    var target_Wood = t.tradeRoutes[count]["target_Wood"];
    var target_Stone = t.tradeRoutes[count]["target_Stone"];
    var target_Ore = t.tradeRoutes[count]["target_Ore"];
    var target_Astone = t.tradeRoutes[count]["target_Astone"];
    var target_Gold = t.tradeRoutes[count]["target_Gold"];

    var ship_Food = t.tradeRoutes[count]["ship_Food"];
    var ship_Wood = t.tradeRoutes[count]["ship_Wood"];
    var ship_Stone = t.tradeRoutes[count]["ship_Stone"];
    var ship_Ore = t.tradeRoutes[count]["ship_Ore"];
    var ship_Astone = t.tradeRoutes[count]["ship_Astone"];
    var ship_Gold = t.tradeRoutes[count]["ship_Gold"];

    var citymax_Food = parseIntNan(Seed.resources[cityID]['rec1'][0] / 3600);
    var citymax_Wood = parseIntNan(Seed.resources[cityID]['rec2'][0] / 3600);
    var citymax_Stone = parseIntNan(Seed.resources[cityID]['rec3'][0] / 3600);
    var citymax_Ore = parseIntNan(Seed.resources[cityID]['rec4'][0] / 3600);
    var citymax_Astone = parseIntNan(Seed.resources[cityID]['rec5'][0]);
    var citymax_Gold = parseIntNan(Seed.citystats[cityID]['gold']);

    var carry_Food = parseIntNan(citymax_Food - target_Food);
    var carry_Wood = parseIntNan(citymax_Wood - target_Wood);
    var carry_Stone = parseIntNan(citymax_Stone - target_Stone);
    var carry_Ore = parseIntNan(citymax_Ore - target_Ore);
    var carry_Astone = parseIntNan(citymax_Astone - target_Astone);
    var carry_Gold = 0;

    if (carry_Food < 0 || ship_Food==false) carry_Food = 0;
    if (carry_Wood < 0 || ship_Wood==false) carry_Wood = 0;
    if (carry_Stone < 0 || ship_Stone==false) carry_Stone = 0;
    if (carry_Ore < 0 || ship_Ore==false) carry_Ore = 0;
    if (carry_Astone < 0 || ship_Astone==false) carry_Astone = 0;
    if (trade_Food > 0 && (carry_Food > trade_Food)) carry_Food = parseIntNan(trade_Food);
    if (trade_Wood > 0 && (carry_Wood > trade_Wood)) carry_Wood = parseIntNan(trade_Wood);
    if (trade_Stone > 0 && (carry_Stone > trade_Stone)) carry_Stone = parseIntNan(trade_Stone);
    if (trade_Ore > 0 && (carry_Ore > trade_Ore)) carry_Ore = parseIntNan(trade_Ore);
    if (trade_Astone > 0 && (carry_Astone > trade_Astone)) carry_Astone = parseIntNan(trade_Astone);

    carry_Astone *= 5; //Multiply by 5 to account for 5 times less carrying capacity
      
    if (t.tradeRoutes[count]['TroopType'] == undefined) 
      var unit = 'unt9';
    else 
      var unit = t.tradeRoutes[count]['TroopType'];
    
    var Troops = parseInt(Seed.units[cityID][unit]);
    
    maxUnits = getMarchSize(cityID);
    if (parseInt(Troops) > maxUnits) 
    { 
      Troops = maxUnits; 
    }
    
    var featherweight = parseInt(Seed.tech.tch10);
    var Load = parseInt(unsafeWindow.unitstats[unit]['5'])
    var maxloadperwagon = Math.floor((featherweight * ((Load/100)*10)) + Load);
    var maxload = (maxloadperwagon * Troops);
    
    // TODO : we need to account for tr boosts here
    
    if(Troops <= 0) 
    {
      return; 
    }

    for (var t = 0; t < Seed.cities.length ; t++) 
    {
      if ( parseInt(Seed.cities[t][0]) == city) 
        var cityname = Seed.cities[t][1];
    }                     
  
    var shift_Food = parseIntNan(maxload / 9); //Total of 9 portions
    var shift_Wood = parseIntNan(maxload / 9);
    var shift_Stone = parseIntNan(maxload / 9);
    var shift_Ore = parseIntNan(maxload / 9);
    var shift_Astone = parseIntNan(maxload / 9 * 5); //Aetherstone takes 5 of 9 portions  

    if ((maxload - carry_Food - carry_Wood - carry_Stone - carry_Ore - carry_Astone) < 0)
    {
      var shift_num=0;
      var shift_spare=0;
        
      // Check: See if load/4 is to big for some resources...
      if (carry_Food < shift_Food) 
      {
        shift_spare += (shift_Food - carry_Food);
        shift_Food = carry_Food;
      }
      
      if (carry_Wood < shift_Wood) 
      {
        shift_spare += (shift_Wood - carry_Wood);
        shift_Wood = carry_Wood;  
      }
      if (carry_Stone < shift_Stone) {
        shift_spare += (shift_Stone - carry_Stone);
        shift_Stone = carry_Stone;
      }
      if (carry_Ore < shift_Ore) {
        shift_spare += (shift_Ore - carry_Ore);
        shift_Ore = carry_Ore;
      }
      if (carry_Astone < shift_Astone) {
        shift_spare += (shift_Astone - carry_Astone);
        shift_Astone = carry_Astone;
      }           
         
      while (shift_spare >1) {
        if (carry_Food < (shift_Food + shift_spare)){
          shift_spare = shift_spare - carry_Food;;
          shift_Food = carry_Food;
        }
        else {
          shift_Food = (shift_Food + shift_spare);
          shift_spare = shift_spare- shift_spare;
        }
        
        if (carry_Wood < (shift_Wood + shift_spare)){
          shift_spare = shift_spare - carry_Wood;;
          shift_Wood = carry_Wood;
        }
        else {
          shift_Wood = shift_Wood + shift_spare;
          shift_spare = shift_spare- shift_spare;
        }
        
        if (carry_Stone < (shift_Stone + shift_spare)){
          shift_spare = shift_spare - carry_Stone;
          shift_Stone = carry_Stone;
        }
        else{
          shift_Stone = shift_Stone + shift_spare;
          shift_spare = shift_spare- shift_spare;
        }
        
        if (carry_Ore < (shift_Ore + shift_spare)){
          shift_spare = shift_spare - carry_Ore;
          shift_Ore = carry_Ore;
        }
        else{
          shift_Ore = shift_Ore + shift_spare;
          shift_spare = shift_spare- shift_spare;
        }
        
        if (carry_Astone < (shift_Astone + shift_spare)){
          shift_spare = shift_spare - carry_Astone;
          shift_Astone = carry_Astone;
        }
        else {
          shift_Astone = shift_Astone + shift_spare;
          shift_spare = shift_spare- shift_spare;
        }
      }

      carry_Food = shift_Food;
      carry_Wood = shift_Wood;
      carry_Stone = shift_Stone;
      carry_Ore = shift_Ore;
      carry_Astone = shift_Astone;
    }
    
    if (maxload > (carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Astone) && ship_Gold==true) 
    {
      if ((maxload - (carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Astone)) > (citymax_Gold - target_Gold))
      {
        carry_Gold = (citymax_Gold - target_Gold);
        
        if (carry_Gold < 0 ) 
          carry_Gold = 0;
      }
      else 
        carry_Gold = (maxload-(carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Astone));
      
      if (trade_Gold > 0 && (carry_Gold > trade_Gold)) 
        carry_Gold = parseInt(trade_Gold);
    }
    
    wagons_needed = ((carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Astone + carry_Gold) / maxloadperwagon);
    wagons_needed = wagons_needed.toFixed(0); 
    
    if (wagons_needed < ((carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Astone + carry_Gold) / maxloadperwagon)) 
      wagons_needed++;  
    
    if ( wagons_needed < Options.minwagons ) 
    { 
      if(DEBUG_TRACE) 
        logit('Small transport skipped'); 
      return; 
    }
        
    params.cid= city;
    params.type = "1";
    params.xcoord = xcoord;
    params.ycoord = ycoord;
    params.r1 = carry_Food;
    params.r2 = carry_Wood;
    params.r3 = carry_Stone;
    params.r4 = carry_Ore;
    params.r5 = parseInt(carry_Astone/5);
    params.gold = carry_Gold;
    
    switch (unit)
    {
      case 'unt1': params.u1 = wagons_needed;break;
      case 'unt2': params.u2 = wagons_needed;break;
      case 'unt3': params.u3 = wagons_needed;break;
      case 'unt4': params.u4 = wagons_needed;break;
      case 'unt5': params.u5 = wagons_needed;break;
      case 'unt6': params.u6 = wagons_needed;break;
      case 'unt7': params.u7 = wagons_needed;break;
      case 'unt8': params.u8 = wagons_needed;break;
      case 'unt9': params.u9 = wagons_needed;break;
      case 'unt10': params.u10 = wagons_needed;break;
      case 'unt11': params.u11 = wagons_needed;break;
      case 'unt12': params.u12 = wagons_needed;break;
    }
    
    if ((carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Astone + carry_Gold) <= 0)
    {
      return;
    }
    
    var _ajaxCall = function()
    {
      var profiler = new CM.Profiler("ResponseTime", "march.php");
      new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
        onSuccess: function (transport) 
        
        {
          profiler.stop();
          var rslt = eval("(" + transport.responseText + ")");
          if (rslt.ok) 
          {
            if (Options.logAutoTransport) 
              actionLog('Trade   From: ' + cityname + "   To: " + xcoord + ',' + ycoord + "    ->   "+ unsafeWindow.unitcost[unit][0] +": " + wagons_needed);
            
            addOutgoingMarch(params, rslt);
            
            CheckUpdateSeed(rslt);
          } 
          else 
          {
            if (rslt.user_action) 
            {
              var user_action = 
              {
                marchWarning: function() 
                {
                  logit('Captcha: [transport] captcha warning');
                  actionLog('Captcha: [transport] captcha warning');
                },
                marchCaptcha: function() 
                {
                  actionLog('Captcha: [transport] triggered captcha');
                  logit('Captcha: [transport] triggered captcha');
                  startCaptcha();
                },
                backOffWaitTime: function() 
                {
                  logit('Captcha: [transport] back off time - ' + rslt.wait_time);
                  actionLog('Captcha: [transport] back off time - ' + rslt.wait_time);
                  params.tt = rslt.tt;
                  setTimeout(_ajaxCall, rslt.wait_time * 1000)
                }
              };
              user_action[rslt.user_action].call();
            }
            else
            {
              if (Options.logAutoTransport) 
                actionLog(''+translate("TRANSPORT FAIL:")+' ' + cityname + ' -> ' + rslt.msg);
            }
          }
        },
        
        onFailure: function () 
        {
          profiler.stop();  
        }
      }, true);
    }
    
    _ajaxCall();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  ManualTransport: function()
  {
    var t = Tabs.transport;
    
    if(Options.captchaTimer > 0) 
    {
      jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error: Cannot send - captcha active") + '</font>');
    } 

    if (document.getElementById ('ptcityX').value == "" || document.getElementById ('ptcityY').value == "") 
    {
      jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error: No destination specified") + '</font>'); 
      return;
    }
    
    if ( t.TroopsNeeded > t.Troops) 
    {
      jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error: Not enough troops for load specified") + '</font>'); 
      return;
    }
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    var unitType = document.getElementById('TransportTroop').value;
    var LoadUnit = (parseInt(Seed.tech.tch10) * ((parseInt(unsafeWindow.unitstats[unitType]['5'])/100)*10)) + parseInt(unsafeWindow.unitstats[unitType]['5']);
    var MaxLoad =  parseInt(Seed.units['city' + t.tcp.city.id][unitType]) * LoadUnit;
    jQuery('#errorSpace').html('Submitting request...please wait');
        
    params.kid = 0;
    params.cid =  t.tcp.city.id;
    params.type = "1";
    params.xcoord = parseInt(document.getElementById ('ptcityX').value);
    params.ycoord = parseInt(document.getElementById ('ptcityY').value);
    params.r1 = parseInt(document.getElementById ('pbtradeamountFood').value);
    params.r2 = parseInt(document.getElementById ('pbtradeamountWood').value);
    params.r3 = parseInt(document.getElementById ('pbtradeamountStone').value);
    params.r4 = parseInt(document.getElementById ('pbtradeamountOre').value);
    params.r5 = parseInt(document.getElementById ('pbtradeamountAstone').value);
    params.gold = parseInt(document.getElementById ('pbtradeamountGold').value);
    
    switch (unitType)
    {
      case 'unt1': params.u1 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt2': params.u2 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt3': params.u3 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt4': params.u4 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt5': params.u5 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt6': params.u6 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt7': params.u7 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt8': params.u8 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt9': params.u9 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt10': params.u10 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt11': params.u11 = parseInt(document.getElementById ('TroopsToSend').value);break;
      case 'unt12': params.u12 = parseInt(document.getElementById ('TroopsToSend').value);break;
    }

    if ((params.r1 + params.r2 + params.r3 + params.r4 + params.r5 + params.gold) <= 0) 
    {
      jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error: Nothing to transport") + '</font>');
      
      return;
    }
    
    var _ajaxCall = function()
    {
      var profiler = new CM.Profiler("ResponseTime", "march.php");
      
      new PriorityAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
      {
        method: "post",
        parameters: params,
        loading: true,
        fastMarch : true,
        
        onSuccess: function (transport) 
        {
          profiler.stop();
          var rslt = eval("(" + transport.responseText + ")");
          if (rslt.ok) 
          {                  
            addOutgoingMarch(params, rslt);
            
            jQuery('#errorSpace').html('Sent: ' + addCommas(params.r1 + params.r2 + params.r3 + params.r4 + params.r5 + params.gold) + ' Resources with ' + addCommas(parseInt(document.getElementById ('TroopsToSend').value)) + ' ' + unsafeWindow.unitcost[unitType][0]);
            
            CheckUpdateSeed(rslt);
          } 
          else 
          {
            if (rslt.user_action) 
            {
              var user_action = 
              {
                marchWarning: function() 
                {
                  logit('Captcha: [transport] captcha warning');
                  actionLog('Captcha: [transport] captcha warning');
                },
                marchCaptcha: function() 
                {
                  actionLog('Captcha: [transport] triggered captcha');
                  logit('Captcha: [transport] triggered captcha');
                  startCaptcha();
                },
                backOffWaitTime: function() 
                {
                  logit('Captcha: [transport] back off time - ' + rslt.wait_time);
                  actionLog('Captcha: [transport] back off time - ' + rslt.wait_time);
                  params.tt = rslt.tt;
                  setTimeout(_ajaxCall, rslt.wait_time * 1000)
                }
              };
              user_action[rslt.user_action].call();
            }

            if (rslt.msg == undefined) 
            {
              jQuery('#errorSpace').html('<FONT COLOR=red>Error: failed to send march</font>');
              // jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error:") + ' ' + unsafeWindow.g_js_strings.errorcode[errorcode] +'</font>');
            } 
            else 
            {
              jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error:") + ' ' + rslt.msg +'</font>'); 
            }
          }
        },
        
        onFailure: function () 
        {
          profiler.stop();
          if(Options.captchaTimer > 0) 
          {
            jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error: Cannot send - captcha active") + '</font>');
          } 
          else 
          {
            jQuery('#errorSpace').html('<FONT COLOR=red>' + translate("Error: Request failed") + '</font>');
          }
        }
      }, true);
    }
    
    _ajaxCall();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show: function()
  {
    var t = Tabs.transport;
    
    clearTimeout (t.timer);
    t.updateTroops();
    t.updateResources();  
    t.timer = setTimeout (t.show, 1000); 
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide: function()
  {
    var t = Tabs.transport;
    clearTimeout (t.timer);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  onUnload: function()
  {
    var t = Tabs.transport;
    
    if (!ResetAll) 
      t.saveTradeRoutes();
    
    if (!ResetAll) 
      t.saveTraderState();
  },
}


/*********************************  Raid Tab ***********************************/
/************** Bot active
(object) queue_atkp = [object Object]
    (object) city73930 = [object Object]
      (object) m6093 = [object Object]
        (number) marchType = 9
        (number) marchStatus = 1
        (string) playerId = 1550996
        (string) cityId = 73930
        (string) botSettingsId = 1479
        (string) botMarchStatus = 1
        (string) botState = 1
        (string) modalState = 0
        (string) restPeriod = 3472
        (string) fromPlayerId = 1550996
        (string) fromCityId = 73930
        (string) fromAllianceId = 2199
        (string) fromXCoord = 159
        (string) fromYCoord = 638
        (undefined) toPlayerId: null = null
        (undefined) toCityId: null = null
        (undefined) toAllianceId: null = null
********/
/************* Bot returning
(object) queue_atkp = [object Object]
    (object) city73930 = [object Object]
      (object) m6093 = [object Object]
        (number) marchType = 9
        (number) marchStatus = 8
        (string) playerId = 1550996
        (string) cityId = 73930
        (string) botSettingsId = 1479
        (string) botMarchStatus = 1
        (string) botState = 1
        (string) modalState = 0
        (string) restPeriod = 3472
        (string) fromPlayerId = 1550996
        (string) fromCityId = 73930
        (string) fromAllianceId = 2199
        (string) fromXCoord = 159
        (string) fromYCoord = 638
        (undefined) toPlayerId: null = null
        (undefined) toCityId: null = null
        (undefined) toAllianceId: null = null
*****/
/******** Bot resting
(object) queue_atkp = [object Object]
    (object) city73930 = [object Object]
      (object) m6093 = [object Object]
        (string) marchType = 9
        (string) marchStatus = 4
        (string) playerId = 1550996
        (string) cityId = 73930
        (string) botSettingsId = 1479
        (string) botMarchStatus = 7
        (string) botState = 1
        (string) modalState = 0
        (string) restPeriod = 3472
        (string) fromPlayerId = 1550996
        (string) fromCityId = 73930
        (string) fromAllianceId = 2199
        (string) fromXCoord = 159
        (string) fromYCoord = 638
        (undefined) toPlayerId: null = null
        (undefined) toCityId: null = null
        (string) toTileId = 451239
        (undefined) toAllianceId: null = null
**********/
/************* March type cheat sheet
cm.BOT_STATUS = {
    BOT_MARCH_UNDEFINED: 0,
    BOT_MARCH_MARCHING: 1,
    BOT_MARCH_RETURNING: 2,
    BOT_MARCH_STOPPED: 3,
    BOT_MARCH_INSUFFICIENT_TROOPS: 4,
    BOT_MARCH_MAX_RAIDS_EXCEEDED: 5,
    BOT_MARCH_TIMED_OUT: 6,
    BOT_MARCH_RESTING: 7
};
cm.MARCH_STATUS = {
    MARCH_STATUS_INACTIVE: 0,
    MARCH_STATUS_OUTBOUND: 1,
    MARCH_STATUS_DEFENDING: 2,
    MARCH_STATUS_STOPPED: 3,
    MARCH_STATUS_RESTING: 4,
    MARCH_STATUS_UNKNOWN: 5,
    MARCH_STATUS_SITUATIONCHANGED: 7,
    MARCH_STATUS_RETURNING: 8,
    MARCH_STATUS_ABORTING: 9
};
cm.MARCH_TYPES = {
    MARCH_TYPE_NONE: 0,
    MARCH_TYPE_TRANSPORT: 1,
    MARCH_TYPE_REINFORCE: 2,
    MARCH_TYPE_SCOUT: 3,
    MARCH_TYPE_ATTACK: 4,
    MARCH_TYPE_REASSIGN: 5,
    MARCH_TYPE_BARBARIAN: 6,
    MARCH_TYPE_MERCENARY: 7,
    MARCH_TYPE_BARBARIAN_REINFORCE: 8,
    MARCH_TYPE_BOT_BARBARIAN: 9
};
************/

 Tabs.Raid = {
  tabDisabled : false,
  tabOrder : 110,
  myDiv : null,
  knt:{},
  Troops:{},
  city:0,
  raidtimer:null,
  rslt:{},
  save:{},
  stopping:false,
  resuming:false,
  deleting:false,
  stopprogress:0,
  stopcount:0,
  activecount:0,
  count:0,
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init : function (div)
  {
    var t = Tabs.Raid;
    t.myDiv = div;
    t.raidtimer = setTimeout(t.checkRaids, 30000);
    setInterval(t.lookup, 2500);
    setInterval(t.sendreport, 1*60*1000);
    
    AddSubTabLink('Stop Raids', t.StopAllRaids, 'pbraidtab');
    AddSubTabLink('Resume Raids', t.ResumeAllRaids, 'pbraidtabRes');
    AddSubTabLink('Delete Raids', t.DeleteAllRaids, 'pbraidtabDel');
    
    
    var m = '<DIV class=pbStat>RAID FUNCTIONS</div><TABLE width=100% height=0% class=pbTab><TR align="center">';
    m += '<TD><INPUT id=pbRaidStart type=submit value="Auto Reset = '+ (Options.RaidRunning?'ON':'OFF') +'" ></td>';
    m += '<TD><INPUT id=pbsendraidreport type=checkbox '+ (Options.foodreport?'CHECKED':'') +'\> Send raid report every ';
    m += '<INPUT id=pbsendreportint value='+ Options.MsgInterval +' type=text size=3 \> hours </td>';
    m += '</tr></table></div>';
    m += '<DIV class=pbStat>ACTIVE RAIDS</div><TABLE width=100% height=0% class=pbTab><TR align="center">';
    m += '<TD><DIV style="margin-bottom:10px;"><span id=ptRaidCity></span></div></td></tr>';
    m+='<TR><TD><DIV style="margin-bottom:10px;"><span id=ptRaidTimer></span></div></td></tr></table>';
    m += '<DIV id=PaintRaids></div>';
    m += '<DIV class=pbStat>SAVED RAIDS</div><TABLE width=100% height=0% class=pbTab><TR align="center">';
    m += '<DIV id=SavedRaids></div>';
    t.myDiv.innerHTML = m;
  
    t.from = new CdispCityPicker ('ptRaidpicker', document.getElementById('ptRaidCity'), true, t.clickCitySelect, 0);
    
    document.getElementById('pbRaidStart').addEventListener('click', t.toggleRaidState, false);
    
    document.getElementById('pbsendraidreport').addEventListener('change', function()
    {
      Options.foodreport = document.getElementById('pbsendraidreport').checked;
      saveOptions();
    }, false);
    
    document.getElementById('pbsendreportint').addEventListener('change', function()
    {
      Options.MsgInterval = parseInt(document.getElementById('pbsendreportint').value);
      saveOptions();
    }, false);
  
    var serverID = getServerId();
    
    t.save = GM_getValue ('SavedRaids_'+serverID);
    
    if (t.save != undefined) 
    t.save = JSON2.parse (t.save);
  
    setInterval (t.paint,1000);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  lookup : function ()
  {
    var t = Tabs.Raid;
    t.activecount=0;
    t.stopcount=0;
    
    for (c = 0 ; c < Seed.cities.length ; c++) 
    {
      cityID = 'city' + Seed.cities[c][0];    
      
      for (b in Seed.queue_atkp[cityID])
      {
        destinationUnixTime = Seed.queue_atkp[cityID][b]['destinationUnixTime']; 
        MarchStatus = Seed.queue_atkp[cityID][b]['marchStatus'];
        MarchType = Seed.queue_atkp[cityID][b]['marchType'];
        botMarchStatus = Seed.queue_atkp[cityID][b]['botMarchStatus'];
        
        if (MarchType == 9 &&  MarchStatus == 3 || MarchStatus==10) 
          t.stopcount++;
        else if (MarchType == 9) 
          t.activecount++;
        
        //alert(MarchType +'/'+  MarchStatus);
      }
    }
    
    //logit(t.stopcount); 
    if (t.resuming == false && t.stopping == false && t.deleting == false && t.activecount != 0)
      document.getElementById('pbraidtab').innerHTML = '<span style="color: #ff6">Stop Raids ('+ t.activecount + ')</span>'
    else if (t.resuming == false && t.stopping == false && t.deleting == false)
      document.getElementById('pbraidtab').innerHTML = '<span style="color: #CCC">Stop Raids ('+ t.activecount + ')</span>'
    
    if (t.resuming == false && t.resuming == false && t.deleting == false && t.stopcount !=0)
      document.getElementById('pbraidtabRes').innerHTML = '<span style="color: #ff6">Resume Raids ('+ t.stopcount + ')</span>'
    else if (t.resuming == false && t.stopping == false && t.deleting == false)
      document.getElementById('pbraidtabRes').innerHTML = '<span style="color: #CCC">Resume Raids ('+ t.stopcount + ')</span>'
    
    if (t.resuming == false && t.stopping == false && t.deleting == false && t.stopcount !=0)
      document.getElementById('pbraidtabDel').innerHTML = '<span style="color: #ff6">Delete Raids ('+ t.stopcount + ')</span>'
    else if (t.resuming == false && t.stopping == false && t.deleting == false)
      document.getElementById('pbraidtabDel').innerHTML = '<span style="color: #CCC">Delete Raids ('+ t.stopcount + ')</span>'
  },
   
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  paint : function () 
  {
    var t = Tabs.Raid;
    var botMarchStat = {0:'Inactive',
              1:'Raiding',
              2:'Returning',
              3:'Stopped',
              4:'Resting',
              5:'Unknown',
              7:'Situation Changed',
              8:'Returning',
              9:'Aborting'};
    var botStat = {0:'Undefined',
              1:'Marching',
              2:'Returning',
              3:'Stopped',
              4:'Insufficient Troops',
              5:'Max Raids Exceeded',
              7:'Timed out',
              8:'Resting'};
    var o = '';
    
    if (t.rslt.settings != undefined) 
      o+= '<FONT size=2px><B>Raid Timer: '+ timestr( 86400 - ( unixTime() - t.rslt.settings.lastUpdated )) +'</b></font>';
    
    document.getElementById('ptRaidTimer').innerHTML = o;
    
    var z ='<TABLE class=pbTab><TR><TD width=60px align=center><A onclick="pbStopAll('+t.cityId+')">STOP</a></td><TD width=70px>Time</td><TD width=85px>Coords</td><TD width=50px>Level</td><TD width=50px></td><TD width=50px><A onclick="pbDeleteAll()">DELETE</a></td></TR>';
    if (t.rslt['queue'] != "")
    {
      for (y in t.rslt['queue']) 
      {
        if (t.rslt['queue'][y]['botMarches'] != undefined) 
        {
          for (k in Seed.queue_atkp['city' + t.cityId])
          {
            if (Seed.queue_atkp['city' + t.cityId][k]['marchId'] == t.rslt['queue'][y]['botMarches']['marchId']) 
            {
              botMarchStatus = Seed.queue_atkp['city' + t.cityId][k]['botMarchStatus'];
              MarchStatus = Seed.queue_atkp['city' + t.cityId][k]['marchStatus'];
              restPeriod = (Seed.queue_atkp['city' + t.cityId][k]['restPeriod']/60); 
              destinationUnixTime = Seed.queue_atkp['city' + t.cityId][k]['destinationUnixTime'];
              returnUnixTime = Seed.queue_atkp['city' + t.cityId][k]['returnUnixTime']
              now = unixTime();
              //z+='<TR><TD>('+ botMarchStatus +'/'+ MarchStatus +')</td>';
              z+='<TR>';
              //if (destinationUnixTime > now && botMarchStatus !=3) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/attacking.jpg></td>';
              if (MarchStatus ==1) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/attacking.jpg></td>';
              //if ((destinationUnixTime - now) <= 0 && botMarchStatus !=3 && returnUnixTime > now) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/returning.jpg></td>';
              if (MarchStatus ==8 && (destinationUnixTime - now) <= 0 && botMarchStatus !=3 && returnUnixTime > now) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/returning.jpg></td>';
              if (MarchStatus == 3) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/autoAttack/raid_stopped_desat.png></td>';
              //if (returnUnixTime < now  && botMarchStatus !=3) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/autoAttack/raid_resting.png></td>';
              if (MarchStatus == 4 || (returnUnixTime < now  && botMarchStatus !=3)) z+='<TD align=center><img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/autoAttack/raid_resting.png></td>';
              
              if (destinationUnixTime >= now) z+='<TD>'+ timestr(Seed.queue_atkp['city' + t.cityId][k]['destinationUnixTime'] - unixTime())+'</td>';
              if (destinationUnixTime <= now) 
              {
                if ((destinationUnixTime - now) <= 0 && returnUnixTime > now) z+='<TD>'+ timestr(returnUnixTime - now)+'</td>';
                if (returnUnixTime <= now) z+='<TD>'+ timestr(now - returnUnixTime)+'</td>';
              }
            }
          }
          
          z += '<TD>('+ t.rslt['queue'][y]['botMarches']['toXCoord'] +','+ t.rslt['queue'][y]['botMarches']['toYCoord']+')</td>';
          z += '<TD align=center>'+ t.rslt['queue'][y]['botMarches']['toTileLevel'] +'</td>';
          if (botMarchStatus == 3) 
            z += '<TD><A onclick="pbEditRaid('+ y +')">Edit</a></td>';
          else 
            z += '<TD><FONT COLOR= "CCCCCC">Edit</font></td>';
          if (botMarchStatus == 3) 
            z += '<TD align=center><A onclick="pbDeleteRaid('+ t.rslt['queue'][y]['botMarches']['marchId']+')">Delete</a></td>';
          else 
            z += '<TD align=center><FONT COLOR= "CCCCCC">Delete</font></td>';
          
          //z +='<TD width=25px></td><TD>Status: '+ botMarchStat[botMarchStatus]+'</td>';
          z += '<TD width=25px></td><TD>Rest Time: '+ timestr(restPeriod) +'</td>';
          z += '</tr>';
        }
      }
    }
    z+='</table>';
    
    if (t.rslt['queue'] == "") 
      z ='<TABLE class=pbTab><TR><TD>No Raids in city!</td></TR>';
    
    document.getElementById('PaintRaids').innerHTML = z;
    
    var check = true;
    
    if (t.save != "")
    {
      var a ='<TABLE class=pbTab><TR><TD width=60px></td><TD width=70px></td><TD width=85px>Coords</td><TD width=50px>Level</td><TD width=50px></td><TD width=50px></td></tr>';
      for (y in t.save)
      {
        if (t.save[y] != undefined && t.cityId == t.save[y]['cityId'])
        {
          a +='<TR><TD align=center><A onclick="pbDeleteSavedRaid('+ t.save[y]['marchId'] +')">X</a></td>';
          a +='<TD></td><TD><FONT COLOR= "CC0000">('+t.save[y]['toXCoord']+','+t.save[y]['toYCoord']+')</font></td>';
          a +='<TD align=center>'+t.save[y]['toTileLevel']+'</td>';
          a +='<TD><A onclick="pbEditSavedRaid('+ y +')">Edit</a></td>';
          a +='<TD align=center><A onclick="pbAddRaid('+ t.save[y]['marchId']+')">Add</a></td></tr>';
          check = false;
        } 
      }
      m+='</table>';
    }
      
    if (check) 
      a ='<TABLE class=pbTab><TR><TD>No Saved Raids in city!</td></TR>';
    
    document.getElementById('SavedRaids').innerHTML = a;    
    
    unsafeWindow.pbDeleteRaid = t.DeleteRaid;
    unsafeWindow.pbEditRaid = t.EditRaid;
    unsafeWindow.pbAddRaid = t.AddRaid;
    unsafeWindow.pbDeleteSavedRaid = t.DeleteSavedRaid;
    unsafeWindow.pbEditSavedRaid = t.EditSavedRaid;
    unsafeWindow.pbStopAll = t.StopCityRaids;
    unsafeWindow.pbDeleteAll = t.DeleteCityRaids;
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DeleteSavedRaid : function (Id)
  {
    var t = Tabs.Raid;
    
    for (yy=0;yy<t.save.length;yy++)
    {
      if (t.save[yy]['marchId'] == Id)
      {
          t.save.splice (yy,1);
      } 
    }
    
    var serverID = getServerId();
    setTimeout (function (){GM_setValue ('SavedRaids_'+serverID, JSON2.stringify(t.save));}, 0);
    
    t.paint();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  EditSavedRaid : function (y)
  {
    var t = Tabs.Raid;
    var pop = new pbPopup ('pbEditRaid', 0,0, 750,350, true);
    
    if (t.popFirst)
    {
      pop.centerMe (mainPop.getMainDiv());  
      t.popFirst = false;
    }
    
    pop.getTopDiv().innerHTML = '<CENTER><B>Edit Saved Raid</b></center>';
    cityId =  t.save[y]['cityId'];
    
    var m = '<BR><TABLE id=pbRaidAdd height=0% class=pbTab><TR align="center">';
    m+='<TR></tr><TR><TD width=25px>X= <INPUT id=toXCoord type=text size=3 maxlength=3 value='+t.save[y]['toXCoord']+'></td>';
    m+='<TD width=10px></td><TD widht=25px>Y= <INPUT id=toYCoord type=text size=3 maxlength=3 value='+ t.save[y]['toYCoord'] +'></td>';
    m+='<TD width=25px></td><TD>Round Trip: '+ timestr((t.save[y]['returnUnixTime'] - t.save[y]['destinationUnixTime'])*2)+ '</td></tr></table>';

    m += '<BR><TABLE id=pbRaidAdd width=100% height=0% class=pbTab><TR align="center">';
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_50.jpg?6545"></td>';
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt1']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt2']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt3']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt4']) +'</td></tr>'
    m += '<TR><TD><INPUT id=Unit1 type=text size=6 maxlength=6 value="'+ t.save[y]['unit1Count']+'"></td>';
    m += '<TD><INPUT id=Unit2 type=text size=6 maxlength=6 value="'+ t.save[y]['unit2Count']+'"></td>';
    m += '<TD><INPUT id=Unit3 type=text size=6 maxlength=6 value="'+ t.save[y]['unit3Count']+'"></td>';
    m += '<TD><INPUT id=Unit4 type=text size=6 maxlength=6 value="'+ t.save[y]['unit4Count']+'"></td></tr>';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_50.jpg?6545"></td>';
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt5']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt6']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt7']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt8']) +'</td></tr>'
    m += '<TR><TD><INPUT id=Unit5 type=text size=6 maxlength=6 value="'+ t.save[y]['unit5Count']+'"></td>';
    m += '<TD><INPUT id=Unit6 type=text size=6 maxlength=6 value="'+ t.save[y]['unit6Count']+'"></td>';
    m += '<TD><INPUT id=Unit7 type=text size=6 maxlength=6 value="'+ t.save[y]['unit7Count']+'"></td>';
    m += '<TD><INPUT id=Unit8 type=text size=6 maxlength=6 value="'+ t.save[y]['unit8Count']+'"></td></tr>';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_50.jpg?6545"></td>';
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt9']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt10']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt11']) +'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_50.jpg?6545"></td>'
    m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt12']) +'</td></tr>'
    m += '<TR><TD><INPUT id=Unit9 type=text size=6 maxlength=6 value="'+ t.save[y]['unit9Count']+'"></td>';
    m += '<TD><INPUT id=Unit10 type=text size=6 maxlength=6 value="'+ t.save[y]['unit10Count']+'"></td>';
    m += '<TD><INPUT id=Unit11 type=text size=6 maxlength=6 value="'+ t.save[y]['unit11Count']+'"></td>';
    m += '<TD><INPUT id=Unit12 type=text size=6 maxlength=6 value="'+ t.save[y]['unit12Count']+'"></td></tr></table>';
    
    m += '<BR><CENTER><SELECT id=AddKnights type=list></select></center>';
    m+= '<BR><CENTER>'+ strButton20('Save', 'id=pbSaveRaid') +'</center>';
          
    pop.getMainDiv().innerHTML = m;
    
    t.getKnights(cityId);
    
    document.getElementById ('AddKnights').value =  t.save[y]['knightId'];
    
    document.getElementById ('pbSaveRaid').addEventListener ('click', function()
    {
      t.save[y]['knightId'] = parseInt(document.getElementById ('AddKnights').value);
      t.save[y]['toXCoord'] = parseInt(document.getElementById ('toXCoord').value);
      t.save[y]['toYCoord'] = parseInt(document.getElementById ('toYCoord').value);
      t.save[y]['unit1Count'] = parseInt(document.getElementById ('Unit1').value);
      t.save[y]['unit2Count'] = parseInt(document.getElementById ('Unit2').value);
      t.save[y]['unit3Count'] = parseInt(document.getElementById ('Unit3').value);
      t.save[y]['unit4Count'] = parseInt(document.getElementById ('Unit4').value);
      t.save[y]['unit5Count'] = parseInt(document.getElementById ('Unit5').value);
      t.save[y]['unit6Count'] = parseInt(document.getElementById ('Unit6').value);
      t.save[y]['unit7Count'] = parseInt(document.getElementById ('Unit7').value);
      t.save[y]['unit8Count'] = parseInt(document.getElementById ('Unit8').value);
      t.save[y]['unit9Count'] = parseInt(document.getElementById ('Unit9').value);
      t.save[y]['unit10Count'] = parseInt(document.getElementById ('Unit10').value);
      t.save[y]['unit11Count'] = parseInt(document.getElementById ('Unit11').value);
      t.save[y]['unit12Count'] = parseInt(document.getElementById ('Unit12').value);
      var serverID = getServerId();
      setTimeout (function (){GM_setValue ('SavedRaids_'+serverID, JSON2.stringify(t.save));}, 0);
      pop.show (false);
    }, false);
    
    pop.show (true);    
    },
      
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  EditRaid : function (y)
  {
      var t = Tabs.Raid;
      var pop = new pbPopup ('pbEditRaid', 0,0, 750,350, true);
      if (t.popFirst){
        pop.centerMe (mainPop.getMainDiv());  
        t.popFirst = false;
      }
      pop.getTopDiv().innerHTML = '<CENTER><B>Edit Raid</b></center>';
      cityId = t.rslt['queue'][y]['botMarches']['cityId'];
      
        var m = '<BR><TABLE id=pbRaidAdd height=0% class=pbTab><TR align="center">';
        m+='<TR></tr><TR><TD width=25px>X= <INPUT id=toXCoord type=text size=3 maxlength=3 value='+t.rslt['queue'][y]['botMarches']['toXCoord']+'></td>';
        m+='<TD width=10px></td><TD widht=25px>Y= <INPUT id=toYCoord type=text size=3 maxlength=3 value='+ t.rslt['queue'][y]['botMarches']['toYCoord'] +'></td>';
        m+='<TD width=25px></td><TD>Round Trip: '+ timestr((t.rslt['queue'][y]['botMarches']['returnUnixTime'] - t.rslt['queue'][y]['botMarches']['destinationUnixTime'])*2)+ '</td></tr></table>';

        m += '<BR><TABLE id=pbRaidAdd width=100% height=0% class=pbTab><TR align="center">';
        m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_50.jpg?6545"></td>';
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt1']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt2']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt3']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt4']) +'</td></tr>'
        m += '<TR><TD><INPUT id=Unit1 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit1Count']+'"></td>';
        m += '<TD><INPUT id=Unit2 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit2Count']+'"></td>';
        m += '<TD><INPUT id=Unit3 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit3Count']+'"></td>';
        m += '<TD><INPUT id=Unit4 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit4Count']+'"></td></tr>';
        
        m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_50.jpg?6545"></td>';
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt5']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt6']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt7']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt8']) +'</td></tr>'
        m += '<TR><TD><INPUT id=Unit5 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit5Count']+'"></td>';
        m += '<TD><INPUT id=Unit6 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit6Count']+'"></td>';
        m += '<TD><INPUT id=Unit7 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit7Count']+'"></td>';
        m += '<TD><INPUT id=Unit8 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit8Count']+'"></td></tr>';
        
        m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_50.jpg?6545"></td>';
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt9']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt10']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt11']) +'</td>'
        m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_50.jpg?6545"></td>'
        m += '<TD>'+ addCommas(Seed.units['city'+cityId]['unt12']) +'</td></tr>'
        m += '<TR><TD><INPUT id=Unit9 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit9Count']+'"></td>';
        m += '<TD><INPUT id=Unit10 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit10Count']+'"></td>';
        m += '<TD><INPUT id=Unit11 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit11Count']+'"></td>';
        m += '<TD><INPUT id=Unit12 type=text size=6 maxlength=6 value="'+ t.rslt['queue'][y]['botMarches']['unit12Count']+'"></td></tr></table>';
        
        m += '<BR><CENTER><SELECT id=AddKnights type=list></select></center>';
        m+= '<BR><CENTER>'+ strButton20('Save', 'id=pbRaidSave') +'</center>';
            
      pop.getMainDiv().innerHTML = m;
      
      t.getKnights(cityId);
      
      document.getElementById ('AddKnights').value =  t.rslt['queue'][y]['botMarches']['knightId'];
      document.getElementById ('pbRaidSave').addEventListener ('click', function()
      {
        var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
                  
        params.pf = 0;
        params.ctrl = 'BotManager';
        params.action = 'editMarch';
        params.settings = {};
        params.settings.cityId = t.rslt['queue'][y]['botMarches']['fromCityId'];
        params.queue = {0:{botMarches:{botMarchStatus:1,botState:1},cityMarches:{}}};     
        params.queue[0].cityMarches.knightId = parseInt(document.getElementById ('AddKnights').value);
        params.queue[0].cityMarches.toXCoord =  parseInt(document.getElementById ('toXCoord').value);
        params.queue[0].cityMarches.toYCoord =  parseInt(document.getElementById ('toYCoord').value);
        params.queue[0].cityMarches.unit0Count = 0; //document.getElementById ('Unit0').value;
        params.queue[0].cityMarches.unit1Count =  parseInt(document.getElementById ('Unit1').value);
        params.queue[0].cityMarches.unit2Count = parseInt(document.getElementById ('Unit2').value);
        params.queue[0].cityMarches.unit3Count = parseInt(document.getElementById ('Unit3').value);
        params.queue[0].cityMarches.unit4Count = parseInt(document.getElementById ('Unit4').value);
        params.queue[0].cityMarches.unit5Count = parseInt(document.getElementById ('Unit5').value);
        params.queue[0].cityMarches.unit6Count = parseInt(document.getElementById ('Unit6').value);
        params.queue[0].cityMarches.unit7Count = parseInt(document.getElementById ('Unit7').value);
        params.queue[0].cityMarches.unit8Count = parseInt(document.getElementById ('Unit8').value);
        params.queue[0].cityMarches.unit9Count = parseInt(document.getElementById ('Unit9').value);
        params.queue[0].cityMarches.unit10Count = parseInt(document.getElementById ('Unit10').value);
        params.queue[0].cityMarches.unit11Count = parseInt(document.getElementById ('Unit11').value);
        params.queue[0].cityMarches.unit12Count = parseInt(document.getElementById ('Unit12').value);
        params.queue[0].cityMarches.marchId =  t.rslt['queue'][y]['botMarches']['marchId'];
        
        new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
        {
          method: "post",
          parameters: params,
          loading: true,
          onSuccess: function(transport){
            var rslt = eval("(" + transport.responseText + ")");
            if (rslt.ok) 
            {
              pop.show (false);
              unsafeWindow.cityinfo_army();
              setTimeout(unsafeWindow.update_seed_ajax, 250);
              setTimeout(t.GetRaids, (750),Seed.cities[i][0]);
            }
          },
        });
      },false);
      
      pop.show (true);    
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DeleteRaid : function (Id)
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    for (y in t.rslt['queue']) 
    {
      if (t.rslt['queue'][y]['botMarches'] != undefined) 
      {
        if (t.rslt['queue'][y]['botMarches']['marchId'] == Id) 
        {
            marchId = t.rslt['queue'][y]['botMarches']['marchId'];
            cityId = t.rslt['queue'][y]['botMarches']['cityId'];
            knightId = t.rslt['queue'][y]['botMarches']['knightId'];
            toTileLevel = t.rslt['queue'][y]['botMarches']['toTileLevel'];
            returnUnixTime = t.rslt['queue'][y]['botMarches']['returnUnixTime'];
            destinationUnixTime = t.rslt['queue'][y]['botMarches']['destinationUnixTime'];
            toXCoord = t.rslt['queue'][y]['botMarches']['toXCoord'];
            toYCoord = t.rslt['queue'][y]['botMarches']['toYCoord'];
            var units = {};
            for (i=1;i<13;i++) units[i] = t.rslt['queue'][y]['botMarches']['unit'+i+'Count'];
        }
      }
    } 
    
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'deleteMarch';
    params.marchId = marchId;
    params.settings = {};
    params.settings.cityId = cityId;
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, {
             method: "post",
             parameters: params,
         loading: true,
         onSuccess: function(transport){
          var rslt = eval("(" + transport.responseText + ")");
                  if (rslt.ok) {
                      var serverID = getServerId();
                      t.save = GM_getValue ('SavedRaids_'+serverID);
                      if (t.save == undefined) t.save =new Array();
            else t.save = JSON2.parse (t.save);
            
                      t.save.push ({
                        marchId:    marchId,
                        cityId:       cityId,
                        knightId:   knightId,
                        toTileLevel:  toTileLevel,
                        returnUnixTime: destinationUnixTime,
                        returnUnixTime: returnUnixTime,
                        toXCoord:   toXCoord,
                        toYCoord:   toYCoord,
                        unit1Count:   units[1],
                        unit2Count:   units[2],
                        unit3Count:   units[3],
                        unit4Count:   units[4],
                        unit5Count:   units[5],
                        unit6Count:   units[6],
                        unit7Count:   units[7],
                        unit8Count:   units[8],
                        unit9Count:   units[9],
                        unit10Count:  units[10],
                        unit11Count:  units[11],
                        unit12Count:  units[12],
                      });
                      var troops = Seed.units["city" + cityId];
                      for (var u = 1; u <= 12; ++u) {
                          var troop_number = parseInt(rslt["unit" + u + "Return"]);
                          if (isNaN(troop_number)) {
                              troop_number = parseInt(Seed.units["city" + cityId]["unt" + u]);
                          } else troop_number = parseInt(rslt["unit" + u + "Return"]) + parseInt(Seed.units["city" + cityId]["unt" + u]);
                          troops["unt" + u] = troop_number;
                      }
                      for (u in Seed.queue_atkp['city' + cityId]){
                        if (Seed.queue_atkp['city' + cityId][u]['marchId'] == marchId){
              Seed.queue_atkp['city' + cityId][u] = "";
                          unsafeWindow.seed.queue_atkp['city' + cityId] = Seed.queue_atkp['city' + cityId];
                        }
                      }
                      
                      for (u in Seed.knights['city' + cityId]){
                        if (Seed.knights['city' + cityId][u]['knightId'] == knightId){
                          Seed.knights['city' + cityId][u]["knightStatus"] = 1;
                          unsafeWindow.seed.knights['city' + cityId] = Seed.knights['city' + cityId];
                        }
                      }
                                                  
                      GM_setValue ('SavedRaids_'+serverID, JSON2.stringify(t.save));
                      t.save = null;
                      unsafeWindow.cityinfo_army();
                      setTimeout(unsafeWindow.update_seed_ajax, 250);
                      t.GetRaids(cityId);
            }
         },
     });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  StopCityRaids : function (cityId)
  {
      var t = Tabs.Raid;
      var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

      
      params.pf = 0;
      params.ctrl = 'BotManager';
      params.action = 'stopAll';
      params.settings = {};

        params.settings.cityId = cityId;
            
       new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, {
              method: "post",
                 parameters: params,
             loading: true,
             onSuccess: function(transport){
              var rslt = eval("(" + transport.responseText + ")");
                        if (rslt.ok) {
                  
                }
             },
         });   
    setTimeout(t.GetRaids, (750), cityId);  
    },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  StopAllRaids : function ()
  {
        var t = Tabs.Raid;
        if (t.stopping == true || t.resuming == true || t.deleting == true) return;
        if (t.activecount == 0) return;
      t.stopping = true;  
          for (i=0;i<Seed.cities.length;i++){
            setTimeout(t.DoAllStop, (i*1500),i);
         }
   },
   
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
   ResumeAllRaids : function ()
   {
        var t = Tabs.Raid;
        if (t.stopping == true || t.resuming == true || t.deleting == true) return;
        if (t.stopcount == 0) return;
        t.resuming = true;
        for (i=0;i<Seed.cities.length;i++){
            setTimeout(t.DoAllResume, (i*1500),i);
        }
    },
   
   
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DeleteAllRaids : function ()
  {
    var t = Tabs.Raid;
    
    if (t.stopping == true || t.resuming == true || t.deleting == true) 
      return;
    
    if (t.stopcount == 0) 
      return;
    
    t.deleting = true;
    count=0;
    t.count = t.stopcount;
    
    for (d = 0; d < Seed.cities.length;d++) 
    {
      cityID = 'city' + Seed.cities[d][0];    
      
      for (e in Seed.queue_atkp[cityID])
      {
        destinationUnixTime = Seed.queue_atkp[cityID][e]['destinationUnixTime']; 
        MarchStatus = Seed.queue_atkp[cityID][e]['marchStatus'];
        MarchType = Seed.queue_atkp[cityID][e]['marchType'];
        
        if (MarchType == 9 && (botMarchStatus == 3 || MarchStatus == 3)) 
        {
          count++;
          setTimeout(t.DoAllDelete, (count*1250), (Seed.queue_atkp[cityID][e]['marchId']),d,count);
        }
      }
    }
  }, 
    
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DoAllStop: function(i) 
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'stopAll';
    params.settings = {};
    params.settings.cityId = Seed.cities[i][0];
            
       new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, {
              method: "post",
                 parameters: params,
             loading: true,
             onSuccess: function(transport){
              var rslt = eval("(" + transport.responseText + ")");
                        if (rslt.ok) {
                            t.stopprogress = t.stopprogress + (100/Seed.cities.length);
                            actionLog('Stopping: '+ Seed.cities[i][1]);
                            updatebotbutton('Stopping: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtab');
                            if (t.stopprogress.toFixed(0) == 100) {
                               t.stopprogress = 0;
                               setTimeout(function(){updatebotbutton('Stop Raids ('+ t.activecount + ')', 'pbraidtab');t.stopping = false;}, (5000));
                            }   
                }
                else {
                    if (rslt.msg == "The system is busy, please try again later") setTimeout (t.DoAllStop, (2000),i);
                    else {
                      t.stopprogress = t.stopprogress + (100/Seed.cities.length);
                      actionLog('Stopping: '+ Seed.cities[i][1] + ' - ' + rslt.msg);
                      updatebotbutton('Stopping: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtab')
                      if (t.stopprogress.toFixed(0) == 100) {
                         t.stopprogress = 0;
                         setTimeout(function(){updatebotbutton('Stop Raids ('+ t.activecount + ')', 'pbraidtab');t.stopping = false;}, (5000));
                      }
                    }
                }
             },
    });  
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DoAllResume: function(i) 
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'resumeAll';
    params.settings = {};
    params.settings.cityId = Seed.cities[i][0];
            
       new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, {
              method: "post",
                 parameters: params,
             loading: true,
             onSuccess: function(transport){
              var rslt = eval("(" + transport.responseText + ")");
                        if (rslt.ok) {
                            t.stopprogress = t.stopprogress + (100/Seed.cities.length);
                            actionLog('Resuming: '+ Seed.cities[i][1]);
                            updatebotbutton('Resuming: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtabRes');
                            if (t.stopprogress.toFixed(0) == 100) {
                               t.stopprogress = 0;
                               setTimeout(function(){updatebotbutton('Resume Raids ('+ t.stopcount + ')', 'pbraidtabRes');t.resuming = false;}, (5000));
                            }   
                }
                else {
                    if (rslt.msg == "The system is busy, please try again later") setTimeout (t.DoAllResume, (2000),i);
                    else {
                      t.stopprogress = t.stopprogress + (100/Seed.cities.length);
                      actionLog('Stopping: '+ Seed.cities[i][1]  + ' - ' + rslt.msg);
                      updatebotbutton('Resuming: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtabRes')
                      if (t.stopprogress.toFixed(0) == 100) {
                         t.stopprogress = 0;
                         setTimeout(function(){updatebotbutton('Resume Raids ('+ t.stopcount + ')', 'pbraidtabRes');t.resuming = false;}, (5000));
                      } 
                    }
                }
             },
    });  
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DoAllDelete : function (Id,city,count)
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    cityID = 'city'+ Seed.cities[city][0];
    
    for (f in Seed.queue_atkp[cityID])
    {
      if (Seed.queue_atkp[cityID][f]['marchId'] == Id) 
      {
          marchId = Seed.queue_atkp[cityID][f]['marchId'];
          cityId = Seed.queue_atkp[cityID][f]['cityId'];
          knightId = Seed.queue_atkp[cityID][f]['knightId'];
          toTileLevel = Seed.queue_atkp[cityID][f]['toTileLevel'];
          returnUnixTime = Seed.queue_atkp[cityID][f]['returnUnixTime'];
          destinationUnixTime = Seed.queue_atkp[cityID][f]['destinationUnixTime'];
          toXCoord = Seed.queue_atkp[cityID][f]['toXCoord'];
          toYCoord = Seed.queue_atkp[cityID][f]['toYCoord'];
          
          var units = {};
          
          for (i=1;i<13;i++) 
            units[i] = Seed.queue_atkp[cityID][f]['unit'+i+'Count'];
      }
    }
    
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'deleteMarch';
    params.marchId = marchId;
    params.settings = {};
    params.settings.cityId = cityId;
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function(transport)
      {
        var rslt = eval("(" + transport.responseText + ")");

        if (rslt != "") 
        {
          var serverID = getServerId();
          
          t.save = GM_getValue ('SavedRaids_'+serverID, "[]");
          
          if (t.save != undefined) 
            t.save = JSON2.parse (t.save);
          
          if (t.save == undefined) 
            t.save =new Array();

          t.save.push ({
            marchId:    marchId,
            cityId:       cityId,
            knightId:   knightId,
            toTileLevel:  toTileLevel,
            returnUnixTime: destinationUnixTime,
            returnUnixTime: returnUnixTime,
            toXCoord:     toXCoord,
            toYCoord:     toYCoord,
            unit1Count:   units[1],
            unit2Count:   units[2],
            unit3Count:   units[3],
            unit4Count:   units[4],
            unit5Count:   units[5],
            unit6Count:   units[6],
            unit7Count:   units[7],
            unit8Count:   units[8],
            unit9Count:   units[9],
            unit10Count:  units[10],
            unit11Count:  units[11],
            unit12Count:  units[12],
          });
                      
          var troops = Seed.units["city" + cityId];
          
          for (var u = 1; u <= 12; ++u) 
          {
            var troop_number = parseInt(rslt["unit" + u + "Return"]);
            if (isNaN(troop_number)) 
            {
              troop_number = parseInt(Seed.units["city" + cityId]["unt" + u]);
            } 
            else
            {
              troop_number = parseInt(rslt["unit" + u + "Return"]) + parseInt(Seed.units["city" + cityId]["unt" + u]);
            }
            
            troops["unt" + u] = troop_number;
          }
          
          setTimeout (function (){GM_setValue ('SavedRaids_'+serverID, JSON2.stringify(t.save));}, 0);
          unsafeWindow.cityinfo_army();   
          setTimeout(unsafeWindow.update_seed_ajax, 250);
        }
      },
    });
    
    t.stopprogress = count * (100/t.count);
    actionLog('Deleting: '+ Seed.cities[city][1]);
    updatebotbutton('Deleting: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtabDel');
    
    if (t.stopprogress.toFixed(0) == 100) 
    {
      t.stopprogress = 0;
      t.GetRaids(cityId);
      
      setTimeout( function()
      {
        updatebotbutton('Delete Raids ('+ t.stopcount + ')', 'pbraidtabDel'); 
        t.deleting  = false;
      }, 5 * 1000);
    } 
  },
  
      
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  DeleteCityRaids : function ()
  {
        var t = Tabs.Raid;
        alert('This button needs to be added...');
        /*var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
  
        
        params.pf = 0;
        params.ctrl = 'BotManager';
        params.action = 'stopAll';
        params.settings = {};
  
          params.settings.cityId = t.cityId;
              
         new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, {
                method: "post",
                   parameters: params,
               loading: true,
               onSuccess: function(transport){
                var rslt = eval("(" + transport.responseText + ")");
                          if (rslt.ok) {
                    
                  }
               },
           }); */     
      },
        
      
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  AddRaid : function (Id)
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    update = {};
    
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'saveMarch';
    params.settings = {};
    params.queue = {0:{botMarches:{botMarchStatus:1,botState:1},cityMarches:{}}};
    
    for (y in t.save){
      if (t.save[y]['marchId'] == Id){
        params.settings.cityId = t.save[y]['cityId'];
        params.queue[0].cityMarches.knightId = t.save[y]['knightId']; //parseInt(document.getElementById('AddKnights').value);
        params.queue[0].cityMarches.toXCoord = t.save[y]['toXCoord'];
        params.queue[0].cityMarches.toYCoord = t.save[y]['toYCoord'];
        params.queue[0].cityMarches.unit0Count = 0;
        params.queue[0].cityMarches.unit1Count = t.save[y]['unit1Count'];
        params.queue[0].cityMarches.unit2Count = t.save[y]['unit2Count'];
        params.queue[0].cityMarches.unit3Count = t.save[y]['unit3Count'];
        params.queue[0].cityMarches.unit4Count = t.save[y]['unit4Count'];
        params.queue[0].cityMarches.unit5Count = t.save[y]['unit5Count'];
        params.queue[0].cityMarches.unit6Count = t.save[y]['unit6Count'];
        params.queue[0].cityMarches.unit7Count = t.save[y]['unit7Count'];
        params.queue[0].cityMarches.unit8Count = t.save[y]['unit8Count'];
        params.queue[0].cityMarches.unit9Count = t.save[y]['unit9Count'];
        params.queue[0].cityMarches.unit10Count = t.save[y]['unit10Count'];
        params.queue[0].cityMarches.unit11Count = t.save[y]['unit12Count'];
        params.queue[0].cityMarches.unit12Count = t.save[y]['unit12Count'];
      }
    } 
     
    new AjaxRequest2(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function(transport)
      {
        var rslt = eval("(" + transport.responseText + ")");
        
        if (rslt.ok) 
        {
          t.GetRaids(params.settings.cityId);
          unsafeWindow.cityinfo_army();
          setTimeout(unsafeWindow.update_seed_ajax, 250);
        
          for (yy=0;yy<t.save.length;yy++)
          {
            if (t.save[yy]['marchId'] == Id)
            {
              t.save.splice (yy,1);
            } 
          }

          var serverID = getServerId();
          setTimeout (function (){GM_setValue ('SavedRaids_'+serverID, JSON2.stringify(t.save));}, 0);
          t.paint();
        } 
        else 
        {
          alert('Error: '+ rslt.msg);   
        }
      },
    });      
  },
        
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  getKnights : function(cityId)
  {
    var t = Tabs.Raid;
    var knights = getFreeKnight(cityId);
    
    document.getElementById('AddKnights').options.length=0;

    var o = document.createElement("option");
    o.text = '--Choose a Knight--';
    o.value = 0;
    
    document.getElementById("AddKnights").options.add(o);
    for (k in knights)
    {
      if (knights[k]["Name"] != undefined)
      {
        var o = document.createElement("option");
        o.text = (knights[k]["Name"] + ' (' + knights[k]["Combat"] +') (' + knights[k]["Status"] +')');
        o.value = knights[k]["ID"];
        document.getElementById("AddKnights").options.add(o);
      }
    }
  },
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  clickCitySelect : function (city)
  {
    var t = Tabs.Raid;
    t.cityId = city['id'];
    t.GetRaids(t.cityId);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  checkRaids : function ()
  {
    var t = Tabs.Raid;
    var now = unixTime();
    
    if(!Options.RaidRunning) 
      return;
    
    if ( (now - Options.RaidReset) > 7200 ) 
    {
      Options.RaidReset = now;
      saveOptions();
      
      for (g=0;g<Seed.cities.length;g++)
      {
        t.citiesdone = "";
        setTimeout(t.resetRaids, (1500*g), Seed.cities[g][0],Seed.cities[g][1]);
      }

      setTimeout(t.postLog, 30000);
    }
    
    t.raidtimer = setTimeout(t.checkRaids, 900000);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  GetRaids : function(cityId)
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
          
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'getMarches';
    params.settings = {};
    params.settings.cityId = cityId;
    
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function(transport)
      {
        var rslt = eval("(" + transport.responseText + ")");

        if (rslt.ok) 
        {
          t.rslt = rslt;
          t.paint();
          unsafeWindow.cityinfo_army();
          setTimeout(unsafeWindow.update_seed_ajax, 250);
        }
      },
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  resetRaids : function(cityId,cityName)
  {
    var t = Tabs.Raid;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
          
    params.pf = 0;
    params.ctrl = 'BotManager';
    params.action = 'resetRaidTimer';
    params.settings = {};
    params.settings.cityId = cityId;
    
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      
      onSuccess: function(transport)
      {
        var rslt = eval("(" + transport.responseText + ")");

        if (rslt.ok) 
        {
          unsafeWindow.cityinfo_army();
          setTimeout(unsafeWindow.update_seed_ajax, 250);
          t.citiesdone += cityName + ' ';
        }
      },
    });
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  postLog : function ()
  {
    var t = Tabs.Raid;
    actionLog('Reset Raidtimer: ' + t.citiesdone);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sendreport: function()
  {
    var t = Tabs.Raid;
    
    if(!Options.foodreport) 
      return;
    
    var now = new Date().getTime()/1000.0;
    now = now.toFixed(0);
    
    if (now < (parseInt(Options.LastReport)+(Options.MsgInterval*60*60))) 
      return;
  
    var total = 0;
    var message = 'Raid Stats: %0A';
    message += '%0A Food Gain (for '+ Options.MsgInterval +' hour of raiding) %0A';
    
    for (q=1;q<=Seed.cities.length;q++)
    {
      var cityID = 'city' + Seed.cities[q-1][0];
      var gain = parseInt(Seed.resources[cityID]['rec1'][0] / 3600) - Options.Foodstatus[q];
      message+= Seed.cities[q-1][1] + ': Start: ' + addCommas(Options.Foodstatus[q]) + ' End :' + addCommas(parseInt(Seed.resources[cityID]['rec1'][0] / 3600)) + ' Gain: ';
      message += addCommas(gain)  + '%0A';
      total += gain;
      Options.Foodstatus[q] = parseInt(Seed.resources[cityID]['rec1'][0] / 3600);
    }
    
    message += '%0A Total food gain : '+addCommas(total)+'%0A';
  
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.emailTo = Seed.player['name'];
    params.subject = "Raid Overview";
    params.message = message;
    params.requestType = "COMPOSED_MAIL";
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (message) 
      {
        var rslt = eval("(" + message.responseText + ")");

        if (rslt.ok) 
        {
        } 
        else 
        {
        }
      },
      
      onFailure: function () 
      {
      },
    });
  
    Options.LastReport = now;
    saveOptions();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  toggleRaidState : function ()
  {
    var t = Tabs.Raid;
    
    if(Options.RaidRunning)
    {
      Options.RaidRunning = false;
      t.raidtimer = null;
      document.getElementById('pbRaidStart').value = 'Auto Reset = OFF';
    } 
    else 
    {
      Options.RaidRunning = true;
      t.raidtimer = setTimeout(t.checkRaids, 5000);
      document.getElementById('pbRaidStart').value = 'Auto Reset = ON';
    }
    
    saveOptions();
  },
  
    
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide : function ()
  {
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {
  },
 }; 
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Autocraft
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.AutoCraft = {
  tabOrder: 20, //CHECKTHIS ?
  tabLabel: "Craft",
  myDiv: null,
  timer: null,
  craftIntervall  : TrainOptions.CraftIntervallMin,
  crafting: [],
  myDiv: null,
  timer: null,
  timerStat: null,
  numcity :-1,
  craftinfo : {},
  craftBusy : {},
  delayTime : 5,

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  init: function(div)
  {
    var t = Tabs.AutoCraft;
    var count = 0;
    
    t.myDiv = div;   
    t.crafting = 
    {
      running: TrainOptions.CraftingRunning,
    };
    
    var m = '<DIV id=pbCraftingDiv class=pbStat>AUTO CRAFTING - SETTINGS</div><TABLE id=pbcraftingfunc width=100% height=0% class=pbTab><TR>';
    
    if(!EnableOptions) 
    {
      t.delayTime = 300;
    }
    
    if (t.crafting.running == false) {
      m += '<TD align="left"><INPUT id=pbCraftRunning type=submit value="Crafting = OFF"></td>';
    } else {
      m += '<TD align="left"><INPUT id=pbCraftRunning type=submit value="Crafting = ON"></td>';
      t.timer=setInterval(t.Start,parseInt(t.delayTime * 1000));
    }
    
    m += '<td align="right"><input type=button value="Save Settings" id="Crafting_Save"></td></tr>';
    m += '<tr>';
    m += '<td>Save at least <INPUT type=text size=6 value='+ Options.craftingSaveAmount +' id=pbCraftingSaveAmount /> Aetherstone</td>';
    m += '</tr>';
    m += '<TR><TD align=right>'+translate("Only craft when throne room preset set")+': <SELECT id=pbThronePresetCraftLimitPreset type=list></select></td></tr>';
    m += '</table></div>';
    m += '<DIV id=pbCraftingList class=pbStat>AUTO CRAFTING - LIST</div><TABLE id=pbcraftingqueues width=100% height=0% class=pbTabLined><TR>';

    m += "<td colspan=2><center><b>Items</b></center></td><td><center><b>Inventory</b></center></td><td><b>Amount</b></td>"; 
    m += "<td colspan=2><center><b>Items</b></center></td><td><center><b>Inventory</b></center></td><td><b>Amount</b></td>"; 
    m += "</tr><tr>";
    
    for(var i=0; i < unsafeWindow.recipelist[1].length; i++)
    {
      var h = parseInt(unsafeWindow.recipelist[1][i].output_item_id);
      
      t.craftinfo[h] = {};
      t.craftinfo[h].recipe_id = unsafeWindow.recipelist[1][i].recipe_id;
      t.craftinfo[h].category = unsafeWindow.recipelist[1][i].category;
      t.craftinfo[h].input = unsafeWindow.recipelist[1][i].input;
      t.craftinfo[h].consolation = unsafeWindow.recipelist[1][i].consolation;
      t.craftinfo[h].requirements = unsafeWindow.recipelist[1][i].requirements;
      
      m += "<td ><center><img src='http://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+ h + ".jpg' width=25></center></td>";
      m += "<td><center>" + unsafeWindow.itemlist["i"+h].name + "</center></td>";
      m += "<td><center><span id=pbCraftItem_" + h + " class=boldGreen>" + parseIntNan(Seed.items["i" + h]) + "</span></center></td>";
      m += "<td><input type=text size=4 id='Craft_nb_"+h+"' value='" + parseIntNan(TrainOptions.CraftingNb[h]) +"'></td>";
      
      if ((count + 1) % 2 == 0) 
      {
        m += "</tr><tr>";
      }
      
      count++;
    }
    
    for(var i=0; i < unsafeWindow.recipelist[3].length; i++)
    {
      var h = parseInt(unsafeWindow.recipelist[3][i].output_item_id);
      
      t.craftinfo[h] = {};
      t.craftinfo[h].recipe_id = unsafeWindow.recipelist[3][i].recipe_id;
      t.craftinfo[h].category = unsafeWindow.recipelist[3][i].category;
      t.craftinfo[h].input = unsafeWindow.recipelist[3][i].input;
      t.craftinfo[h].consolation = unsafeWindow.recipelist[3][i].consolation;
      t.craftinfo[h].requirements = unsafeWindow.recipelist[3][i].requirements;
      
      m += "<td ><center><img src='http://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+ h + ".jpg' width=25></center></td>";
      m += "<td><center>"+unsafeWindow.itemlist["i"+h].name+"</center></td>";
      m += "<td><center><span id=pbCraftItem_" + h + " class=boldGreen>"+parseIntNan(Seed.items["i"+h])+"</span></center></td>";
      m += "<td><input type=text size=4 id='Craft_nb_"+h+"' value='"+ parseIntNan(TrainOptions.CraftingNb[h]) +"'></td>";
      
      if ((count + 1) % 2 == 0) 
      {
        m += "</tr><tr>";
      }
      
      count++;
    }
    
    m += "</table>";
    m += '<DIV id=pbCraftingStats class=pbStat>AEHTERSTONES AND CRAFTING TIME</div><span id="CraftStat"></span>';

    t.myDiv.innerHTML = m;

    jQuery("#pbThronePresetCraftLimitPreset").append(
      jQuery('<option></option>').val(0).html("---")
    );

    for (i = 1 ; i <= Seed.throne.slotNum ; i++)
    {
      jQuery("#pbThronePresetCraftLimitPreset").append(
        jQuery('<option></option>').val(i).html(i)
      );
    }

    jQuery("#pbThronePresetCraftLimitPreset").val(Options.craftingThronePreset);

    jQuery("#pbThronePresetCraftLimitPreset").change(function()
    {
      Options.craftingThronePreset = this.value; 
      saveOptions();
    });

    jQuery('#pbCraftingSaveAmount').bind("keyup change", function(event) 
    { 
      switch(event.type)
      {
        case "keyup":
          this.value = this.value.replace(/[^0-9\.]/g,'');
          break;
          
        case "change":
          Options.craftingSaveAmount = parseIntWithDefault(this.value, 100000);
          if(this.value != Options.craftingSaveAmount)
          {
              this.value = Options.craftingSaveAmount;
          }
          saveOptions();
          break;
      }
    });
    
    window.addEventListener('unload', t.onUnload, false);
       
    document.getElementById("Crafting_Save").addEventListener ('click', function (){t.saveCraftState()}, false);
    document.getElementById("pbCraftRunning").addEventListener ('click', function (){t.toggleStateRunning(this)}, false);   

    setInterval(t.updateItemCount, 5 * 1000);
  }, 
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateItemCount : function()
  {
    logit("Crafting: update item count");
    for(var i=0; i < unsafeWindow.recipelist[1].length; i++)
    {
      var h = parseInt(unsafeWindow.recipelist[1][i].output_item_id);
      var percentage = 0;
      
      if(TrainOptions.CraftingStats[h])
      {
        if (TrainOptions.CraftingStats[h].fail == 0)
        {
          percentage = 100;
        }
        else if(TrainOptions.CraftingStats[h].success == 0)
        {
          percentage = 0;
        }
        else
        {
          percentage = +TrainOptions.CraftingStats[h].success * 100 / (+TrainOptions.CraftingStats[h].success + TrainOptions.CraftingStats[h].fail);
        }
      }
      
      jQuery('#pbCraftItem_' + h).text(parseIntNan(Seed.items["i" + h]) + " [" + percentage.toFixed(0) + "%]");
    }
    
    for(var i=0; i < unsafeWindow.recipelist[3].length; i++)
    {
      var h = parseInt(unsafeWindow.recipelist[3][i].output_item_id);
      var percentage = 0;
      
      if(TrainOptions.CraftingStats[h])
      {
        if (TrainOptions.CraftingStats[h].fail == 0)
        {
          percentage = 100;
        }
        else if(TrainOptions.CraftingStats[h].success == 0)
        {
          percentage = 0;
        }
        else
        {
          percentage = +TrainOptions.CraftingStats[h].success * 100 / (+TrainOptions.CraftingStats[h].success + TrainOptions.CraftingStats[h].fail);
        }
      }
      
      jQuery('#pbCraftItem_' + h).text(parseIntNan(Seed.items["i" + h]) + " [" + percentage.toFixed(0) + "%]");
      var h = parseInt(unsafeWindow.recipelist[3][i].output_item_id);
      jQuery('#pbCraftItem_' + h).text(parseIntNan(Seed.items["i" + h]) + " [" + percentage.toFixed(0) + "%]");
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  changeCraft : function (valueId, optionName, callOnChange)
  {
    var t = Tabs.AutoCraft;
    var e = document.getElementById(valueId);
    
    e.value = TrainOptions[optionName];
    e.addEventListener ('change', eventHandler, false);
    
    function eventHandler ()
    {
      TrainOptions[optionName] = this.value;
      saveTrainOptions();
      if (callOnChange)
      callOnChange (this.value);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateStat: function() 
  {
    var t = Tabs.AutoCraft;
    var rownum = 0;
    
    function _row (name, row, noTotal, typee) 
    {
      if (rownum++ % 2)
      {
        style = '';
      }
      else
      {
        style = ' style="background: #e8e8e8"';
      }
      
      var tot = 0;
      
      var m = '';
      m += '<tr style="background: #fff" align=right' + style+ '><td' + style + '><b>' + name + '</b></td>';
      
      if (noTotal)
      {
        m += '<td' + style + '>&nbsp;</td>';
      } 
      else 
      {
        for (i = 0; i < row.length ; i++)
        {
          tot += row[i];
        }
        
        m += '<td style="background: #ffc">';
        
        if (tot < 0) 
        {
          m += "<span class=boldRed>" + addCommas(tot) + "</span>";
        } 
        else 
        {
          m += addCommas(tot);
        }

        m += '</td>';
      }
      
      for (i = 0 ; i < row.length ; i++)
      {
        m += '<td' + style + '>';

        if (row[i] < Options.craftingSaveAmount) 
        {
          m += "<span class=boldRed>" + addCommas(row[i]) + "</span>";
        } 
        else 
        {
          m += addCommas(row[i]);
        }
        
        m += '</td>';
      }
   
      m += '</tr>';
      
      return m;
    }

    clearTimeout(t.timerStat);
    var str = "<table class=pbTabOverview cellpadding=0 cellspacing=0>";
    str += "<tr  align=center>";
    str += "<td width=55 align=center></td>";
    str += "<td width=88 style='background: #ffc; font-size:150%' align=center><span class=oohfancy>TOTAL</span></td>";
    
    for(i = 0; i < Cities.numCities; i++) 
    {
      cityID = 'city'+ Cities.cities[i].id;
         
      str += "<td width=81><span class=oohfancy>"+ Cities.cities[i].name.substring(0,10) + "</SPAN></td>";
    }

    rows = [];
    var now = unixTime();
    rows[0] = [];

    for(i=0; i<Cities.numCities; i++) 
    {
      cityID = 'city'+ Cities.cities[i].id;
      rows[0][i] = parseInt(Seed.citystats[cityID].gold[0]);
    }

    for (r = 1 ; r < 6 ; r++)
    {
      rows[r] = [];

      for(i = 0; i < Cities.numCities; i++) 
      {
        cityID = 'city'+ Cities.cities[i].id;

        if (r==5)
        {
          rows[r][i] = parseInt(Seed.resources[cityID]['rec'+r][0]);
        }
        else
        {
          rows[r][i] = parseInt(Seed.resources[cityID]['rec'+r][0] / 3600);
        }
      }
    }

    str += _row ('<img height=18 src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/aetherstone_30.png>', rows[5], false, 0);
    str += '<tr style="background: #e8e8e8" align=right><td><img height=20 src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/items/70/3.jpg title="Crafting"></b></td><td>&nbsp;</td>';

    for(i = 0 ; i < Cities.numCities ; i++) 
    {
      var totTime = 0;
      
      if (Seed.queue_craft["city" + Cities.cities[i].id].length > 0) 
      {
        var q=Seed.queue_craft["city" + Cities.cities[i].id][0];
        var totTime = 0;

        totTime = q.craftingEtaUnixTime - now;
        
        if (totTime < 0)
          totTime = 0;
        
        if (getCityBuilding(Cities.cities[i].id,20).count>0 && totTime == 0)
          affuichage = '<SPAN class=boldRed><B>'+ timestr(totTime) +'</b></span>';
        else
          affuichage = timestr(totTime);
      
        str +="<td><span onclick='Crafting("+Cities.cities[i].id+");'>"+ affuichage + "</span></td>";  

      } 
      else 
      {
        affuichage = timestr(totTime);
        
        if (getCityBuilding(Cities.cities[i].id,20).count>0)
          affuichage = '<SPAN class=boldRed><B>'+ timestr(totTime) +'</b></span>';
        
        str +="<td><span onclick='Crafting("+Cities.cities[i].id+");'>"+affuichage+"</span></td>";
      }
    }    
    
    str +="</tr>";    
           
    document.getElementById("CraftStat").innerHTML=str;
    t.timerStat = setTimeout(function() { t.updateStat(); }, 2000);
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  updateCraftnb : function() 
  {
    var t = Tabs.AutoCraft;
    
    for(var h in t.craftinfo) 
    {
      if (document.getElementById("Craft_nb_" +h)) 
      {
        document.getElementById("Craft_nb_"+h).value = parseInt(TrainOptions.CraftingNb[h]) ;
      }
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  saveCraftState : function() 
  {
    var t = Tabs.AutoCraft;
    
    TrainOptions.CraftingRunning =  t.crafting.running;
    
    for(var h in t.craftinfo) 
    {
      if (document.getElementById("Craft_nb_" +h)) 
      {
        TrainOptions.CraftingNb[h] = document.getElementById("Craft_nb_"+h).value;
      }
    }
    
    saveTrainOptions();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  toggleStateRunning: function(obj)
  {
    var t = Tabs.AutoCraft;
    obj = document.getElementById('pbCraftRunning');
    
    if (t.crafting.running == true) 
    {
      t.crafting.running = false;
      t.saveCraftState();
      
      if (obj) 
      {
        obj.value = "Crafting = OFF";
      }
      
      clearInterval(t.timer);
    }
    else 
    {
      t.crafting.running = true;
      t.saveCraftState();
      
      if (obj) 
      {
        obj.value  = "Crafting = ON";
      }
      
      t.timer = setInterval(t.Start, parseInt(t.delayTime * 1000));
    }
    
    t.updateCraftnb();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  Start: function() 
  {
    var t = Tabs.AutoCraft;
    
    if(!TrainOptions.CraftingRunning) 
    {
      clearInterval(t.timer);
      return;
    }
    
    if (Options.craftingThronePreset != 0) 
    {
      if (Seed.throne.activeSlot != Options.craftingThronePreset) 
      {
          return;
      }
    }

    if (t.numcity<Cities.numCities-1) 
    {
      t.numcity++;
    } 
    else 
    {
      t.numcity=0; 
    }
    
    var c=t.numcity;
    var cityId=Cities.cities[c].id;
     
    var ret=getCityBuilding(cityId,20).count;
    if (ret==0) 
    { 
      t.Start();
      logit("Crafting: city no fey tower - " + Cities.byID[cityId].name);

      return;
    }
    
    if (parseInt(Seed.resources["city" + cityId]['rec5'][0]) < Options.craftingSaveAmount) 
    {
      logit("Crafting: not enough astone - " + Cities.byID[cityId].name);
      return;
    }
    
    var table = [];
    for(var d in TrainOptions.CraftingNb) 
    {
      if (parseInt(TrainOptions.CraftingNb[d])>0) 
      {
        // added in from new version, still to be checked
        // if(parseInt(t.craftinfo[d].requirements.building) <= parseInt(getCityBuilding(cityId,20).maxLevel))

        table.push (d);
      }
    }

    var itemId;
    var attempts = 10;
    var requiredIngredients;
    
    while(attempts-- > 0) 
    {
      itemId = table[Math.floor(Math.random() * table.length)];
      
      requiredIngredients = true;
      var items = t.craftinfo[itemId].input.items;
      // logit(JSON2.stringify(items,null,2));
      
      for(item in items) 
      {
        if(items.hasOwnProperty(item)) 
        {
          if (parseIntNan(items[item]) > parseIntNan(Seed.items["i" + item])) 
          {
            requiredIngredients = false;   
          }            
        }
      }
      
      if(requiredIngredients == true) 
      {
        break;
      }
    }

    if(requiredIngredients == false) 
    {
      logit("Crafting: could not identify something to make based on ingredients available");
      return;
    }

    for(item in items) 
    {
      if(items.hasOwnProperty(item)) 
      {
        Seed.items["i" + item] -= parseIntNan(items[item]);
      }
    }

    var recipeId = t.craftinfo[itemId].recipe_id;
    var category = t.craftinfo[itemId].category;
    var i=Seed.queue_craft["city"+cityId];
     
    var now = unixTime();
    var totTime = 0;

    while(i.length > 0) 
    {
      var q = i[0];
      totTime = q.craftingEtaUnixTime - now;

      if (totTime > 0) 
      {
        logit("Crafting: city busy - " + Cities.byID[cityId].name);
        return;
      } 
      else 
      {
        logit("Crafting: removed expired craft item");
        var expired = i.shift();
      }
    } 
    
    if(!t.craftBusy[cityId] || t.craftBusy[cityId] == false) 
    {
      t.CraftingItem(cityId,  itemId, recipeId, category);
      t.craftBusy[cityId] = true;
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  ItemName: function (itemId) 
  {
    if(unsafeWindow.itemlist["i"+itemId]) 
    {
      return unsafeWindow.itemlist["i"+itemId].name;
    } 
    else 
    {
      return "*Unknown Item*";
    }
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  CraftingItem: function (currentcity, itemId, recipeId, category) 
  {
    var t = Tabs.AutoCraft;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.action="craft";
    params.ctrl="Crafting";
    params.cityId = currentcity;
    params.insurance=false;
    params.itemId=itemId;
    params.recipeId=recipeId;
    params.categoryId=category;
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/_dispatch.php" + unsafeWindow.g_ajaxsuffix, 
    { 
      method: "post", 
      parameters: params,
      loading: true,
      
      onSuccess: function (transport) 
      {
        var o=eval("("+transport.responseText+")");
        
        if(o.ok===true)
        {
          if(!TrainOptions.CraftingStats[itemId])
          {
            TrainOptions.CraftingStats[itemId] = {};
            TrainOptions.CraftingStats[itemId].success = 0;
            TrainOptions.CraftingStats[itemId].fail = 0;
          }

          if (o.status=="error") 
          {
            logit("Crafting: error [City: "+ Cities.byID[currentcity].name + "] - " + o.errorMessage);
            //logit(JSON2.stringify(t.craftinfo[itemId].input,null,2));
            
            var items = t.craftinfo[itemId].input.items;

            for(item in items) 
            {
              if(items.hasOwnProperty(item)) 
              {
                Seed.items["i" + item] += parseIntNan(items[item]);
              }
            }
          } 
          else if(o.status=="failure") 
          {
            actionLog("Crafting: failure [City: "+ Cities.byID[currentcity].name + "] - " + t.ItemName(itemId));
            
            if (t.craftinfo[itemId].consolation) 
            {
              Seed.items["i" + t.craftinfo[itemId].consolation]++;
            }

            t.CraftingItem(currentcity,  itemId, recipeId, category);
            TrainOptions.CraftingStats[itemId].fail++;
            saveTrainOptions();
          } 
          else if (o.status=="success") 
          {
            //actionLog ('<b>'+culang.auto+' '+culang.crafting+'</b>:  <span class=boldGreen>OK</span> #'+ (TrainOptions.CraftingNb[itemId] -1)+' ');
            actionLog("Crafting: success [City: "+ Cities.byID[currentcity].name + "] - " + t.ItemName(itemId));
            TrainOptions.CraftingNb[itemId] =  TrainOptions.CraftingNb[itemId] -1;
            t.updateCraftnb();

            if(!Seed.queue_craft["city"+currentcity]) 
            {
              Seed.queue_craft["city"+currentcity]=[];
            }

            var n={};
            n.recipeId=recipeId;
            n.craftingUnixTime=o.time.startTime;
            n.craftingEtaUnixTime=o.time.endTime;
            n.craftingId=o.craftingId;
            n.categoryId=null;
            n.recipeIndex=null;
            unsafeWindow.seed.queue_craft["city"+currentcity].push(n);
            unsafeWindow.queue_changetab_building();
            unsafeWindow.update_queue();
            //t.Start()
            TrainOptions.CraftingStats[itemId].success++;
            saveTrainOptions();
          }
        }
        t.craftBusy[currentcity] = false;
      },
      
      onFailure: function () 
      { 
        logit("Crafting: Comms error");   
        t.craftBusy[currentcity] = false;
      }
    });
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  show : function ()
  {
    var t = Tabs.AutoCraft;
    clearTimeout(t.timerStat);
    t.updateStat();
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  hide: function()
  {
    var t = Tabs.AutoCraft;
    clearTimeout(t.timerStat);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  onUnload: function()
  {
      var t = Tabs.AutoCraft;
       t.saveCraftState();
  },
};
  
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: AutoDF
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Barb = {
  tabLabel: 'AutoDF',
  tabOrder : 125,
  myDiv : null,
  MapAjax : new CMapAjax(),
  popFirst : true,
  opt : {},
  nextattack : null,
  searchRunning : false,
  tilesSearched : 0,
  tilesFound : 0,
  curX : 0,
  curY : 0,
  lastX : 0,
  firstX : 0,
  firstY : 0,
  lastY : 0,
  knt:{},
  barbArray:{},
  lookup:1,
  city:0,
  deleting:false,
  
    
  init : function (div)
  {
    var t = Tabs.Barb;
    t.myDiv = div;
 
    var m = '<DIV id=pbTowrtDivF class=pbStat>AUTOMATED FOREST FUNCTION</div><TABLE id=pbbarbingfunctions width=100% height=0% class=pbTab><TR align="center">';
   
    if (AttackOptions.Running == false) 
    {
      m += '<TD><INPUT id=AttSearch type=submit value="Attack = OFF"></td>';
         //updatebotbutton("BOT");
    } 
    else 
    {
      m += '<TD><INPUT id=AttSearch type=submit value="Attack = ON"></td>';
         //updatebotbutton("BOT (AA)");
    }
    
    m += '<TD><INPUT id=troopselect type=submit value="Select troops"></td>';
    m += '<TD><INPUT id=Options type=submit value="Options"></td>';
    m += '</tr></table></div>';
    
    m += '<DIV id=pbTraderDivD class=pbStat>FOREST STATS</div>';
  
    m += '<TABLE id=pbbarbstats width=95% height=0% class=pbTab><TR align="left"><TR>';
    
    for(i=0;i<Seed.cities.length;i++)
    {
      m += '<TD>' + Seed.cities[i][1] +'</td>';
    }
    
    m+='</tr><TR>';
    
    for(i=0;i<Seed.cities.length;i++)
    {
      m += '<TD><DIV><span id='+ 'pdtotalcity' + i +'></span></div></td>';
    }
    
    m+='</tr><TR>';
    for(i=0;i<Seed.cities.length;i++)
    {
      m += '<TD><DIV><span id='+ 'pddatacity' + i +'></span></div></td>';
    }
    
    m+='</tr><TR>'
    
    for(i=0;i<Seed.cities.length;i++)
    {
      m += '<TD><DIV><span id='+ 'pddataarray' + i +'></span></div></td>';
    }
   
    m+='</tr></table><TABLE id=pbbarbstats width=95% height=0% class=pbTab><TR align="left"><TR>';
   
    for (i=0;i<=6;i++) 
    {
      m+='<TD><DIV><span id='+ 'pberror' + i +'></span></div></td>';
    }
    
    m+='</tr></table>';
    m += '<DIV id=pbTraderDivD class=pbStat>FOREST OPTIONS</div>';
    m += '<TABLE width=95% height=0% class=ptTab><TR align="left">';
    
    for(i=0;i<Seed.cities.length;i++)
    {
      m += '<TR><TD>' + Seed.cities[i][1] +'</td>';
      
      for (w=1;w<=10;w++)
      {
        m += '<TD class=pblevelopt><INPUT id=pbcity'+i+'level'+w+' type=checkbox unchecked=true>Lvl:'+w+'</td>';
      }
    }
    
    t.myDiv.innerHTML = m;

    saveAttackOptions();
    t.checkBarbData();

    for(i=0;i<Seed.cities.length;i++)
    {
      var element = 'pdtotalcity'+i;
      if (t.barbArray[i+1] == undefined) 
        document.getElementById(element).innerHTML = 'No Data';
      else 
        document.getElementById(element).innerHTML =  'Forests:' + t.barbArray[i+1].length;
    }
    
    for(i=0;i<Seed.cities.length;i++)
    {
      for (w=1;w<=10;w++)
      {
        document.getElementById('pbcity'+i+'level'+w).checked = AttackOptions.Levels[i+1][w]; 
      }
    }
    
    document.getElementById('AttSearch').addEventListener('click', function(){t.toggleBarbState(this)} , false);
    document.getElementById('Options').addEventListener('click', t.barbOptions , false);
    document.getElementById('troopselect').addEventListener('click', t.troopOptions , false);
    var element_class = document.getElementsByClassName('pblevelopt');
    for (k=0;k<element_class.length;k++)
    {
      element_class[k].addEventListener('click', t.saveLevelOptions , false);
    }
  },
  
  saveLevelOptions : function()
  {
    for(i=0;i<Seed.cities.length;i++)
    {
      AttackOptions.Levels[i+1][0]=false;
      for (w=1;w<=10;w++)
      {
        var ele = document.getElementById('pbcity'+i+'level'+w);
        AttackOptions.Levels[i+1][w]=ele.checked;
        
        if (ele.checked)          
          AttackOptions.Levels[i+1][0]=true;
      }   
    }
    
    saveAttackOptions();
  },
   
  troopOptions: function()
  {
   var t = Tabs.Barb;
   var troopDef = 
   [
      ['Supply', 1],
      ['Miltia', 2],
      ['Scout', 3],
      ['Pikes', 4],
      ['Swords', 5],
      ['Archers', 6],
      ['Cavalry', 7],
      ['Heavies', 8],
      ['Wagons', 9],
      ['Ballista', 10],
      ['Rams', 11],
      ['Cats', 12],
    ];
    
    if(t.troopselect == null) 
      t.troopselect = new pbPopup ('pbtroopselect', 0, 0, 850, 450, true, function(){t.saveTroops();});
    
    t.troopselect.centerMe (mainPop.getMainDiv());  
    var z= '<DIV id=pbTraderDivD class=pbStat>TROOP SELECTION</div><TABLE width=100%><TR>';
    z+='<TD></td>';
    
    for(var i=0; i<troopDef.length; i++)
      z+='<TD>'+troopDef[i][0]+'</td>';
    
    z+='<TD>MIN dist</td><TD>MAX dist</td>';
    
    for(i=0;i<10;i++)
    {
      z += '<TR><TD>Level '+(i+1)+': </td>';
      for(var j=0; j<troopDef.length; j++)
      {
        z += '<TD><INPUT id="level'+i+'troop'+j+'" type=text size=4 maxlength=6 value="'+AttackOptions.Troops[i+1][j+1]+'" /></td>';
      }
      z+='<TD align=left><INPUT id=Mindist'+i+' type=text size=3 maxlength=3 value="'+AttackOptions.MinDistance[i+1]+'"</td>';
      z+='<TD align=right><INPUT id=dist'+i+' type=text size=3 maxlength=3 value="'+AttackOptions.Distance[i+1]+'"</td>';
      z+='</tr>';       
    }
   
    z+='</table>';
    t.troopselect.getMainDiv().innerHTML = z;
    t.troopselect.show(true);
  },
  
  barbOptions: function()
  {
    var t = Tabs.Barb;
    
    if(t.barboptions == null) 
    {
      t.barboptions = new pbPopup ('pbbarboptions', 0,0, 375,350, true);
    }
    
    t.barboptions.centerMe (mainPop.getMainDiv());  
    t.barboptions.getTopDiv().innerHTML = '<CENTER><b>Dark Forest Options for server '+getServerId()+'</b></CENTER>';
    
    var y = '<DIV style="max-height:400px; overflow-y:auto;"><DIV class=pbStat>RESET FORESTS</div><TABLE width=100%>';
    y +='<TR><TD style="margin-top:5px; text-align:center;"><INPUT id=pbresetbarbs type=submit value="Reset Forests"></td>';
    y +='<TD style="margin-top:5px; text-align:center;"><INPUT id=pbpaintbarbs type=submit value="Show forests"></td>';
    y += '<TD><SELECT id=pbcity type=list></td></tr></table>';
    y +='<table width=100%><TD colspan=2 style="margin-top:5px; text-align:center;"><DIV class=pbStat> OPTIONS </div></td>';
    y +='<TR><TD>Attack interval: </td><td><INPUT id=pbsendint type=text size=4 maxlength=3 value='+ AttackOptions.SendInterval +' \> seconds</td></tr>';
    y +='<TR><TD>Max search distance: </td><td><INPUT id=pbmaxdist type=text size=4 maxlength=3 value='+ AttackOptions.MaxDistance +' \></td></tr>';
    y +='<TR><TD>Keep rallypoint slot(s) free: </td><Td><INPUT id=rallyclip type=text size=3 maxlength=2 value="'+AttackOptions.RallyClip+'" \> </td></tr>';
    y +='<TR><TD><INPUT id=pbreport type=checkbox '+(AttackOptions.UpdateEnabled?'CHECKED':'')+'\> Reset search every </td><td><INPUT id=pbmsgint type=text size=3 maxlength=2 value='+AttackOptions.UpdateInterval+' \>minutes</td></tr>';
    y +='<TR><TD> Skip city after </td><td><INPUT id=barbstopsearch type=text size=3 value='+AttackOptions.stopsearch+' \> tries.</td></tr>';
    y +='<TR><TD>Method : </td><Td> '+htmlSelector({distance:'Closest first', level:'Highest level first', lowlevel:'Lowest level first'}, AttackOptions.Method, 'id=pbmethod')+'</td></tr>';
    y +='<TR><TD>Knight priority : </td><td>'+htmlSelector({0:'Lowest combat skill', 1:'Highest combat skill'}, AttackOptions.knightselector, 'id=barbknight')+'</td></tr>';
    y +='<tr><td>Minimum knight Combat level to send: </td><td><input id=barbMinKnight type=text size=3 value='+AttackOptions.barbMinKnight+' \></td></tr>';
    y +='<tr><td>Maximum knight Combat level to send: </td><td><input id=barbMaxKnight type=text size=3 value='+AttackOptions.barbMaxKnight+' \></td></tr>';
    y+='</table></td></tr></table>';
    
    t.barboptions.getMainDiv().innerHTML = y;
    t.barboptions.show(true);
  
    document.getElementById('pbcity').options.length=0;
  
    for (i=0;i<Seed.cities.length;i++)
    {
      var o = document.createElement("option");
      o.text = Seed.cities[i][1]
      o.value = i+1;
      document.getElementById("pbcity").options.add(o);
    }
     
    document.getElementById('pbpaintbarbs').addEventListener('click', function()
    {
      t.showBarbs(document.getElementById("pbcity").value,Seed.cities[document.getElementById("pbcity").value -1][1]);
    },false);
    
    document.getElementById('pbresetbarbs').addEventListener('click', t.deletebarbs,false);
    
    document.getElementById('pbmethod').addEventListener('change', function()
    {
      AttackOptions.Method=document.getElementById('pbmethod').value;
      saveAttackOptions();
      t.checkBarbData();
    },false);
    
    document.getElementById('barbknight').addEventListener('change', function()
    {
      AttackOptions.knightselector=document.getElementById('barbknight').value;
      saveAttackOptions();
    },false);
    
    document.getElementById('pbreport').addEventListener('change', function()
    {
      AttackOptions.UpdateEnabled=document.getElementById('pbreport').checked;
      saveAttackOptions();
    },false);
    
    document.getElementById('pbmsgint').addEventListener('change', function()
    {
      AttackOptions.UpdateInterval=parseInt(document.getElementById('pbmsgint').value);
      saveAttackOptions();
    },false);
    
    document.getElementById('pbsendint').addEventListener('change', function()
    {
      if(parseInt(document.getElementById('pbsendint').value) <5) //Set minimum attack interval to 5 seconds
        document.getElementById('pbsendint').value = 5;
      AttackOptions.SendInterval=parseInt(document.getElementById('pbsendint').value);
      saveAttackOptions();
    },false);
    
    document.getElementById('pbmaxdist').addEventListener('change', function()
    {
      if(parseInt(document.getElementById('pbmaxdist').value) > 75)
        document.getElementById('pbmaxdist').value = 75;
      AttackOptions.MaxDistance=parseInt(document.getElementById('pbmaxdist').value);
      saveAttackOptions();
    },false);
    
    document.getElementById('rallyclip').addEventListener('change', function()
    {
      AttackOptions.RallyClip=parseInt(document.getElementById('rallyclip').value);
      saveAttackOptions();
    },false);
  
    document.getElementById('barbMinKnight').addEventListener('change', function()
    {
      AttackOptions.barbMinKnight=parseInt(document.getElementById('barbMinKnight').value);
      saveAttackOptions();
    },false);
    
    document.getElementById('barbMaxKnight').addEventListener('change', function()
    {
      AttackOptions.barbMaxKnight=parseInt(document.getElementById('barbMaxKnight').value);
      saveAttackOptions();
    },false);
    
    document.getElementById('barbstopsearch').addEventListener('change', function()
    {
      document.getElementById('barbstopsearch').value = parseInt(document.getElementById('barbstopsearch').value)>0?document.getElementById('barbstopsearch').value:1
      AttackOptions.stopsearch=parseInt(document.getElementById('barbstopsearch').value);
      saveAttackOptions();
    },false);    
  },
  
  showBarbs: function (citynumber,cityname) 
  {
    var t = Tabs.Barb;
    var popTradeRoutes = null;
    t.popTradeRoutes = new pbPopup('pbShowBarbs', 0, 0, 500, 500, true, function() {clearTimeout (1000);});
    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbShowBarbs" id="pbBars">';       
    t.popTradeRoutes.getMainDiv().innerHTML = '</table></div>' + m;
    t.popTradeRoutes.getTopDiv().innerHTML = '<TD><B>Dark Forests for city: '+cityname+'</td>';
    t.paintBarbs(citynumber,cityname);
    t._addTabHeader(citynumber,cityname);
    t.popTradeRoutes.show(true) ;
  },
  
  paintBarbs: function(i,cityname)
  {
    var t = Tabs.Barb;
    for (k=(t.barbArray[i].length-1);k>=0;k--)
    {
        t._addTab(i,cityname,k+1,t.barbArray[i][k]['x'], t.barbArray[i][k]['y'],t.barbArray[i][k]['dist'], t.barbArray[i][k]['level']);
    }
  },
    
  _addTab: function(citynumber,cityname,queueId,X,Y,dist,level)
  {
    logit("AutoDF: Entering _addTab");

    var t = Tabs.Barb;
    var row = document.getElementById('pbBars').insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = queueId;
    row.insertCell(1).innerHTML = X;
    row.insertCell(2).innerHTML = Y;
    row.insertCell(3).innerHTML = dist;
    row.insertCell(4).innerHTML = level;
    row.insertCell(5).innerHTML = '<a class="button20" id="barbdel_' + queueId + '"><span>Delete</span></a>';
    document.getElementById('barbdel_' + queueId).addEventListener('click', function()
    {
      t.deleteBarbElement(citynumber,queueId,cityname, true);
    }, false);
    
    logit("AutoDF: Leaving _addTab");
  },
   
  _addTabHeader: function(citynumber,cityname) 
  {
    logit("AutoDF: Entering _addTabHeader");

    var t = Tabs.Barb;
    var row = document.getElementById('pbBars').insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = "City";
    row.insertCell(1).innerHTML = "X";
    row.insertCell(2).innerHTML = "Y";
    row.insertCell(3).innerHTML = "Dist.";
    row.insertCell(4).innerHTML = "Level";
    row.insertCell(5).innerHTML = '<a class="button20" id="barbdelAll"><span>Delete ALL</span></a>';
    document.getElementById('barbdelAll').addEventListener('click', function()
    {
      t.deleteBarbsCity(citynumber,cityname);
    }, false);

    logit("AutoDF: Leaving _addTabHeader");
  },   
     
  deleteBarbElement: function(citynumber,queueId,cityname,showFlag)
  {
    logit("AutoDF: Entering deleteBarbElement");
    
    var t = Tabs.Barb;
    var queueId = parseInt(queueId);
    var myarray = t.barbArray[citynumber];
    if (myarray) 
    {
      myarray.splice((queueId-1), 1);
      GM_setValue('DF_' + Seed.player['name'] + '_city_' + citynumber + '_' + getServerId(), JSON2.stringify(myarray));
      t.checkBarbData();
      if (showFlag) t.showBarbs(citynumber,cityname);
    }
    else 
    {
      //logit("not found");
    }
    
    logit("AutoDF: Leaving deleteBarbElement");
  },
    
  deleteBarbsCity: function(citynumber,cityname)
  {
    logit("AutoDF: Entering deleteBarbsCity");
    
    var t = Tabs.Barb;
    var queueId = parseInt(queueId);
    AttackOptions.Update[citynumber][1] = 0;
    GM_deleteValue('DF_' + Seed.player['name'] + '_city_' + citynumber + '_' + getServerId())
    t.checkBarbData();
    t.showBarbs(citynumber,cityname);
    reloadKOC();

    logit("AutoDF: Leaving deleteBarbsCity");
  },  
  
  saveTroops: function()
  {
    logit("AutoDF: Entering saveTroops");
    for(i = 0 ; i < 10 ; i++)
    {
      for (w = 0 ; w < 12 ; w++)
      {
        AttackOptions.Troops[i+1][w+1] = parseIntNan(document.getElementById('level'+i+'troop'+w).value);
      }
    
      if(parseIntNan(document.getElementById('dist'+i).value) > AttackOptions.MaxDistance)
        document.getElementById('dist'+i).value = AttackOptions.MaxDistance;
      
      AttackOptions.MinDistance[i+1] = parseIntNan(document.getElementById('Mindist'+i).value);
      AttackOptions.Distance[i+1] = parseIntNan(document.getElementById('dist'+i).value);     
    }
   
    saveAttackOptions();
    logit("AutoDF: Leaving saveTroops");
  },
  
  deletebarbs: function()
  {
    logit("AutoDF: Entering deletebarbs");
    for (i = 1 ; i <= Seed.cities.length ; i++)
    {
      AttackOptions.Update[i][1] = 0;
      GM_deleteValue('DF_' + Seed.player['name'] + '_city_' + i + '_' + getServerId())
    }
    reloadKOC();
    logit("AutoDF: Leaving deletebarbs");
  },

  checkBarbData: function()
  {
    var t = Tabs.Barb;
    
    logit("AutoDF: Entering checkBarbData");

    if(!AttackOptions.Running) 
      return;
      
    for (i = 1 ; i <= Seed.cities.length ; i++)
    {
    
      // if(GM_getValue('Barbs_' + Seed.player['name'] + '_city_' + i + '_' + getServerId())) //Remove old auto barb data
      // GM_deleteValue('Barbs_' + Seed.player['name'] + '_city_' + i + '_' + getServerId());
    
      if (!AttackOptions.Levels[i][0]) 
        continue; //Skip city if not selected
    
      t.barbArray[i] = [];
      var myarray = JSON2.parse(GM_getValue('DF_' + Seed.player['name'] + '_city_' + i + '_' + getServerId(),"[]"));
    
      if ((myarray == undefined || myarray.length == 0) && t.searchRunning==false) 
      {
        t.lookup=i;
      
        if(parseInt(AttackOptions.Update[t.lookup][1]) >= parseInt(AttackOptions.stopsearch)) 
          continue; //Skip if search results are empty more than X times
      
        t.searchRunning = true;
        t.opt.startX = parseInt(Seed.cities[(i-1)][2]);
        t.opt.startY = parseInt(Seed.cities[(i-1)][3]);  
        t.clickedSearch();
        break;
      }
    
      if (myarray)
      {
        if(AttackOptions.Method == 'distance') 
          t.barbArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['dist'];b = b['dist'];return a == b ? 0 : (a < b ? -1 : 1);});
        if(AttackOptions.Method == 'level') 
          t.barbArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['level']+a['dist'];b = b['level']+b['dist'];return a == b ? 0 : (a > b ? -1 : 1);});
        if(AttackOptions.Method == 'lowlevel') 
          t.barbArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['level']+a['dist'];b = b['level']+b['dist'];return a == b ? 0 : (a < b ? -1 : 1);});
        
        GM_setValue('DF_' + Seed.player['name'] + '_city_' + i + '_' + getServerId(), JSON2.stringify(t.barbArray[i]));
      }
      
      AttackOptions.Update[i][1] = 0;
      saveAttackOptions();
    }
    t.nextattack = setTimeout(t.getnextCity, parseInt((Math.random()*3000)+2000));
    
    logit("AutoDF: Leaving checkBarbData");
  },
  
  toggleBarbState: function(obj)
  {
    logit("AutoDF: Entering toggleBarbState");
    var t = Tabs.Barb;
  
    if (AttackOptions.Running == true) 
    {
      AttackOptions.Running = false;
      obj.value = "Attack = OFF";
      saveAttackOptions();
      t.nextattack = null;
    } 
    else 
    {
      AttackOptions.Running = true;
      obj.value = "Attack = ON";
      saveAttackOptions();
      t.checkBarbData();
      t.nextattack = setTimeout(t.getnextCity, parseInt((Math.random()*3000)+2000));
    }
    logit("AutoDF: Leaving toggleBarbState");
  },
  
  barbing : function()
  {
    logit("AutoDF: Entering barbing");

    var t = Tabs.Barb;
    var city = t.city;
     
    citynumber = Seed.cities[city-1][0];
    cityID = 'city' + citynumber; 

    var freeMarchSlots = getFreeMarchSlots(cityID);
    var rallyPoint = getMaxMarches(CityID);
    
    var element1 = 'pddatacity'+(city-1);
    document.getElementById(element1).innerHTML = 'Sent: ' + AttackOptions.BarbsDone[city]; 
    var element2 = 'pddataarray'+(city-1); 
    document.getElementById(element2).innerHTML =  'RP: (' + freeMarchSlots + '/' + rallyPoint +')';
     
    if (freeMarchSlots <= AttackOptions.RallyClip)
      return;
      
    t.getAtkKnight(cityID);
    if (t.knt.toSource() == "[]") 
      return; 
    var kid = t.knt[0].ID;
     
    if(t.barbArray[city].length > 0)
    {
      var barbinfo = t.barbArray[city].shift();
    }
    else if(!t.searchRunning)
    {
      t.checkBarbData();
      return;
    } 
    else 
    {
      return;
    }
    
    var check=0;
    var barblevel = parseInt(barbinfo.level);
    
    if (AttackOptions.Levels[city][barbinfo.level])
    {
      check=1;
    }
    
    if (barbinfo.dist < AttackOptions.MinDistance[barblevel] || barbinfo.dist > AttackOptions.Distance[barblevel])
    {
      check=0;
      GM_setValue('DF_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.barbArray[city]));
      return;
    }

    // check troop levels in city
    var trps = AttackOptions.Troops[barblevel];
    var num_troops = 0;
    for (var ii = 1 ; ii < 13 ; ii++) 
    {
      if (parseInt(trps[ii]) > Seed.units[cityID]['unt'+ii]) check = 0;
      num_troops += trps[ii];
    }
    
    if (num_troops == 0) 
      check = 0;
         
    if (check == 0)
    {
      t.barbArray[city].push(barbinfo);
      GM_setValue('DF_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.barbArray[city]));
      return;
    }
     
    var element = 'pdtotalcity'+(city-1);
    if (t.barbArray[city] == undefined) 
      document.getElementById(element).innerHTML = 'No Data';
    else 
      document.getElementById(element).innerHTML =  'Forests:' + t.barbArray[city].length;
     
    var xcoord = barbinfo['x'];
    var ycoord = barbinfo['y'];
    
    t.doBarb(citynumber,city,xcoord,ycoord,barblevel,kid,trps);
    saveAttackOptions();

    logit("AutoDF: Leaving barbing");
  },

  getnextCity: function()
  {
    var t = Tabs.Barb;
    
    if(t.searchRunning || !AttackOptions.Running) 
      return;
  
    var city = t.city+1;
    
    if (city>Seed.cities.length)
    {
      city=1;
    }
  
    t.city = city;
  
    if(AttackOptions.UpdateEnabled)
    {
      var now = unixTime();
      
      if(now > parseInt(AttackOptions.Update[city][0] + (AttackOptions.UpdateInterval*60)))
      {
        AttackOptions.Update[city][1]=0;
        t.barbArray[city] = []; //Clears data if last update was more than X minutes
        GM_setValue('DF_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.barbArray[city]));
      }
    }
  
    if(AttackOptions.Levels[city][0])
    {
      t.barbing();
      t.nextattack = setTimeout(t.getnextCity, parseInt((Math.random()*3)+AttackOptions.SendInterval)*1000);
    } 
    else 
    {
      t.getnextCity();
    }
  },
  
  // this has not been replaced for now as it is a special case that checks experience and also sorts in different orders  
  getAtkKnight : function(cityID)
  {
    var t = Tabs.Barb;
    t.knt = new Array();
    
    for (k in Seed.knights[cityID])
    {
      var knight = Seed.knights[cityID][k];
      var level = parseInt(Math.sqrt(parseInt(knight.experience) / 75)) + 1;
      var unpoints = level - parseInt(knight.skillPointsApplied);
      var cityLeaders = Seed.leaders[cityID];
      
      if ( knight.knightStatus == 1 && 
           cityLeaders.resourcefulnessKnightId != knight.knightId && 
           cityLeaders.politicsKnightId != knight.knightId && 
           cityLeaders.combatKnightId != knight.knightId && 
           cityLeaders.intelligenceKnightId != knight.knightId && 
           knight.combat >= AttackOptions.barbMinKnight && 
           (parseInt(knight.combat) + parseInt(unpoints)) <= AttackOptions.barbMaxKnight) 
      {
        t.knt.push ({
          Name:   knight.knightName,
          Combat: knight.combat,
          ID:   knight.knightId,
        });
      }
    }
    
    t.knt = t.knt.sort(function sort(a,b) 
    {
      a = parseInt(a['Combat']);
      b = parseInt(b['Combat']);
      
      if(parseInt(AttackOptions.knightselector) > 0)
        return a == b ? 0 : (a > b ? -1 : 1);
      else
        return a == b ? 0 : (a < b ? -1 : 1);
    });
  },
    
  doBarb: function(cityID,counter,xcoord,ycoord,level,kid,trps)
  {
    var t = Tabs.Barb;
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    params.cid=cityID;
    params.type=4;
    params.kid=kid;
    params.xcoord = xcoord;
    params.ycoord = ycoord;
    
    for (ii=1; ii<13; ii++) 
    {
      if(parseInt(trps[ii]) > 0)
      {
        params['u'+ii]=trps[ii];
      }
    }
        
    AttackOptions.BarbsTried++;

    document.getElementById('pberror1').innerHTML = 'Tries:'+ AttackOptions.BarbsTried; 
      
    var profiler = new CM.Profiler("ResponseTime", "march.php");
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,

      onSuccess: function (transport) 
      {
        profiler.stop();
        var rslt = eval("(" + transport.responseText + ")");
        
        if (rslt.ok) 
        {
          addOutgoingMarch(params, rslt);
          
          var slots=0;
          
          for(var k in Seed.queue_atkp['city'+cityID])
          {
            slots++;
          }
          
          if(Seed.queue_atkp['city'+cityID].toSource() == "[]")
          {
            slots = 0;
          }
          
          AttackOptions.BarbsDone[counter]++;
          var element1 = 'pddatacity'+(counter-1);
          document.getElementById(element1).innerHTML = 'Sent: ' + AttackOptions.BarbsDone[counter]; 
          var now = new Date().getTime()/1000.0;
          now = now.toFixed(0);
          GM_setValue('DF_' + Seed.player['name'] + '_city_' + counter + '_' + getServerId(), JSON2.stringify(t.barbArray[counter]));
          saveAttackOptions();
          
          CheckUpdateSeed(rslt);
        } 
        else 
        {
          if (rslt.user_action) 
          {
            var user_action = 
            {
              marchWarning: function() 
              {
                logit('Captcha: [df] captcha warning');
                actionLog('Captcha: [df] captcha warning');
              },
              marchCaptcha: function() 
              {
                actionLog('Captcha: [df] triggered captcha');
                logit('Captcha: [df] triggered captcha');
                startCaptcha();
              },
              backOffWaitTime: function() 
              {
                logit('Captcha: [df] back off time - ' + rslt.wait_time);
                actionLog('Captcha: [df] back off time - ' + rslt.wait_time);
                params.tt = rslt.tt;
                setTimeout(_ajaxCall, rslt.wait_time * 1000)
              }
            };
            user_action[rslt.user_action].call();
          }
          
          //logit( inspect(rslt,3,1));
          if (rslt.error_code != 8 && 
              rslt.error_code != 213 && 
              rslt.error_code == 210) 
          {
            AttackOptions.BarbsFailedVaria++;
          }
          
          if (rslt.error_code == 213) 
          {
            AttackOptions.BarbsFailedKnight++;
          }
          
          if (rslt.error_code == 210) 
            AttackOptions.BarbsFailedRP++;
          
          if (rslt.error_code == 8) 
            AttackOptions.BarbsFailedTraffic++;
          
          if (rslt.error_code == 104) 
          {
            AttackOptions.BarbsFailedBog++;
            GM_setValue('DF_' + Seed.player['name'] + '_city_' + counter + '_' + getServerId(), JSON2.stringify(t.barbArray[counter]));
            saveAttackOptions();
          }
          
          document.getElementById('pberror2').innerHTML = 'Excess Traffic errors:' + AttackOptions.BarbsFailedTraffic; 
          document.getElementById('pberror3').innerHTML = 'Rally Point errors: '+ AttackOptions.BarbsFailedRP;
          document.getElementById('pberror4').innerHTML = 'Knight errors:' + AttackOptions.BarbsFailedKnight;
          document.getElementById('pberror5').innerHTML = 'Other errors:' + AttackOptions.BarbsFailedVaria;
          document.getElementById('pberror6').innerHTML = 'Bog errors:' + AttackOptions.BarbsFailedBog;
          //unsafeWindow.Modal.showAlert(printLocalError((rslt.error_code || null), (rslt.msg || null), (rslt.feedback || null)))
        }
      },
      
      onFailure: function () 
      {
        profiler.stop();
      }
    });
    
    saveAttackOptions();
  },
  
  sendreport: function()
  {
    var t = Tabs.Barb;
    var total = 0;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.emailTo = Seed.player['name'];
    params.subject = "Barb Overview";
    var message = 'Barbing Stats: (Sent/Total)' + '%0A';
    
    for (x=1;x<=Seed.cities.length;x++)
    {  
      message+= Seed.cities[x-1][1] + ': (' + AttackOptions.BarbsDone[x] + '/' + t.barbArray[x].length +')' + '%0A';
    }
    
    message += '%0A'+ 'Excess traffic errors: ' + AttackOptions.BarbsFailedTraffic +'%0A';
    message += 'Rallypoint errors: ' + AttackOptions.BarbsFailedRP +'%0A';
    message += 'Knight errors: ' + AttackOptions.BarbsFailedKnight +'%0A';
    message += 'Other errors: ' + AttackOptions.BarbsFailedVaria +'%0A';
    message += 'Actual sent attacks: ' + (AttackOptions.BarbsTried - AttackOptions.BarbsFailedTraffic - AttackOptions.BarbsFailedRP - AttackOptions.BarbsFailedKnight -  AttackOptions.BarbsFailedVaria) +'%0A';
    message += '%0A'+'%0A' + 'Food Gain (for '+AttackOptions.MsgInterval+' hour of barbing)' +'%0A';
    for (q=1;q<=Seed.cities.length;q++)
    {
      var cityID = 'city' + Seed.cities[q-1][0];
      var gain = parseInt(Seed.resources[cityID]['rec1'][0] / 3600) - AttackOptions.Foodstatus[q];
      message+= Seed.cities[q-1][1] + ': Start: ' + addCommas(AttackOptions.Foodstatus[q]) + ' End :' + addCommas(parseInt(Seed.resources[cityID]['rec1'][0] / 3600)) + ' Gain: ';
      message += addCommas(gain)  + '%0A';
      total += gain;
    }
  
    message += '%0A Total food gain : '+addCommas(total)+'%0A';
    params.message = message;
    params.requestType = "COMPOSED_MAIL";
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      onSuccess: function (message) {
          var rslt = eval("(" + message.responseText + ")");
          if (rslt.ok) {
          } else {
          }
      },
      onFailure: function () {
      },
    });  
  },
  
  clickedSearch : function ()
  {
    var t = Tabs.Barb;
    
    t.opt.maxDistance = parseInt(AttackOptions.MaxDistance); 
    t.opt.searchDistance = (t.opt.maxDistance*2);
    
    if(t.opt.maxDistance > 40)
    {
      t.opt.searchDistance = 40;
    }
    
    t.opt.searchShape = 'circle'; 
    t.mapDat = [];
    t.firstX =  t.opt.startX - t.opt.maxDistance;
    t.lastX = t.opt.startX + t.opt.maxDistance;
    t.firstY =  t.opt.startY - t.opt.maxDistance;
    t.lastY = t.opt.startY + t.opt.maxDistance;
    t.tilesSearched = 0;
    t.tilesFound = 0;
    t.curX = t.firstX;
    t.curY = t.firstY;
    var xxx = t.MapAjax.normalize(t.curX);
    var yyy = t.MapAjax.normalize(t.curY);
    var element = 'pddatacity'+(t.lookup-1);
    document.getElementById(element).innerHTML = 'Searching at '+ xxx +','+ yyy;
   
    setTimeout (function(){t.MapAjax.request (xxx, yyy, t.opt.searchDistance, t.mapCallback)}, MAP_DELAY);
  },
  
  mapCallback : function (left, top, width, rslt)
  {
    var t = Tabs.Barb;
    
    if (!t.searchRunning)
      return;
    
    if (!rslt.ok)
    {
      t.stopSearch ('ERROR: '+ rslt.errorMsg);
      return;
    }
    
    map = rslt.data;
  
    for (k in map)
    {
      if (map[k].tileType==54 && AttackOptions.Levels[t.lookup][map[k].tileLevel])
      {
        var dist = distance (t.opt.startX, t.opt.startY, map[k].xCoord, map[k].yCoord);
     
        if(dist <= parseInt(AttackOptions.MaxDistance))
          if(dist <= parseInt(AttackOptions.Distance[map[k].tileLevel]))
            t.mapDat.push ({time:0,x:map[k].xCoord,y:map[k].yCoord,dist:dist,level:map[k].tileLevel});
      }
    }
    
    t.tilesSearched += (t.opt.searchDistance*t.opt.searchDistance);

    t.curX += t.opt.searchDistance;
    if (t.curX > t.lastX)
    {
      t.curX = t.firstX;
      t.curY += t.opt.searchDistance;
      if (t.curY > t.lastY)
      {
        t.stopSearch('Found: ' + t.mapDat.length);
        return;
      }
    }
    
    var x = t.MapAjax.normalize(t.curX);
    var y = t.MapAjax.normalize(t.curY);
    var element = 'pddatacity'+(t.lookup-1);
    document.getElementById(element).innerHTML = 'Searching at '+ x +','+ y;
    setTimeout (function(){t.MapAjax.request (x, y, t.opt.searchDistance, t.mapCallback)}, MAP_DELAY);
  },
  
  stopSearch : function (msg)
  {
    var t = Tabs.Barb;
    var element = 'pddatacity'+(t.lookup-1);
    document.getElementById(element).innerHTML = msg;
  
    GM_setValue('DF_' + Seed.player['name'] + '_city_' + t.lookup + '_' + getServerId(), JSON2.stringify(t.mapDat));
    AttackOptions.Update[t.lookup][0] = unixTime();
    AttackOptions.Update[t.lookup][1]++;
    t.searchRunning = false;
    saveAttackOptions();
    t.checkBarbData();
    return;
  },
  
  hide : function (){
  
  },

  show : function (){
  
  },

}; 



/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Inventory
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Inventory = {
  myDiv: null,
  general: [],
  combat: [],
  resources: [],
  chest: [],
  court: [],
  type: null,
  queue:[],
  isBusy:false,
  counter:0,
  max:0,
  
  init: function(div){
    var t = Tabs.Inventory;
    t.myDiv = div;
    
    var m = "<DIV class=pbStat>Inventory Tab</div>\
        <CENTER><span class=boldRed>***Use at own risk***</span></center>\
        <TABLE width=100% ><TR>\
        <TD width=50%><input type=submit id=pbinventory_general value='General' />\
          <input type=submit id=pbinventory_combat value='Combat' />\
          <input type=submit id=pbinventory_resources value='Resources' />\
          <input type=submit id=pbinventory_chest value='Chest' />\
          <input type=submit id=pbinventory_court value='Court' /></td>\
        <TD width=50% align=center ><input type=submit id=pbinventory_start value='Start' /></td>\
          </tr></table>\
        <DIV class=pbStat>Items</div>\
        <DIV id=pbinventory></div>\
        <DIV id=pbinventory_info></div>";
    t.myDiv.innerHTML = m;
    t.sort_Items();
    
    $("pbinventory_general").addEventListener('click', t.display_general, false);
    $("pbinventory_combat").addEventListener('click', t.display_combat, false);
    $("pbinventory_resources").addEventListener('click', t.display_resources, false);
    $("pbinventory_chest").addEventListener('click', t.display_chest, false);
    $("pbinventory_court").addEventListener('click', t.display_court, false);
    $("pbinventory_start").addEventListener('click', t.start, false);
    
    $("pbinventory_general").click();
  },
  
  sort_Items : function (){
    var t = Tabs.Inventory;
    for(var k in unsafeWindow.ksoItems){
      var item = unsafeWindow.ksoItems[k];
      if(item.count > 0 && item.usable){
        if(item.category == 1){
          t.general.push(item);
        }
        if(item.category == 3){
          t.combat.push(item);
        }
        if(item.category == 4){
          t.resources.push(item);
        }
        if(item.category == 5){
          t.chest.push(item);
        }
        if(item.category == 6){
          t.court.push(item);
        }
        
      }
    }
  },
  
  display_general : function (){
    var t = Tabs.Inventory;
    t.type = "general";
    var div = document.getElementById("pbinventory");
    var count = 0;
    var m = "<TABLE>";
    m += "<TR><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='10px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='20px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td></tr><TR>";
    for (var k in t.general){
      var item = t.general[k];
      if(!item.name) continue;
      m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
      m += "<TD><input type=checkbox class='pbinv_general' data-ft='"+JSON.stringify(item)+"' /></td>";
      m += "<TD><img width='20px' height='20px' src='https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+item.id+".jpg' /> "+item.name+"</td>";
      m += "<TD><input type=text size=3 id='pb_inv_general_"+item.id+"' /></td>";
      m += "<TD>"+item.count+"</td>";
      m += (count%3 == 2)?"</tr>":"";
      count++;
    }
    m += "</table>";
    div.innerHTML = (count!=0)?m:"<CENTER>No useable items in this category</CENTER>";
  },
  
  display_combat : function ()
  {
    var t = Tabs.Inventory;
    t.type = "combat";
    var div = document.getElementById("pbinventory");
    var count = 0;
    var m = "<TABLE>";
    m += "<TR><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='10px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='20px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td></tr><TR>";
    for (var k in t.combat){
      var item = t.combat[k];
      if(!item.name) continue;
      m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
      m += "<TD><input type=checkbox class='pbinv_combat' data-ft='"+JSON.stringify(item)+"' /></td>";
      m += "<TD><img width='20px' height='20px' src='https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+item.id+".jpg' /> "+item.name+"</td>";
      m += "<TD><input type=text size=3 id='pb_inv_combat_"+item.id+"' /></td>";
      m += "<TD>"+item.count+"</td>";
      m += (count%3 == 2)?"</tr>":"";
      count++;
    }
    m += "</table>";
    div.innerHTML = (count!=0)?m:"<CENTER>No useable items in this category</CENTER>";
  },
  
  display_resources : function ()
  {
    var t = Tabs.Inventory;
    t.type = "resources";
    var div = document.getElementById("pbinventory");
    var count = 0;
    var m = "<TABLE>";
    m += "<TR><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='10px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='20px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td></tr><TR>";
    for (var k in t.resources){
      var item = t.resources[k];
      if(!item.name) continue;
      m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
      m += "<TD><input type=checkbox class='pbinv_resources' data-ft='"+JSON.stringify(item)+"' /></td>";
      m += "<TD><img width='20px' height='20px' src='https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+item.id+".jpg' /> "+item.name+"</td>";
      m += "<TD><input type=text size=3 id='pb_inv_resources_"+item.id+"' /></td>";
      m += "<TD>"+item.count+"</td>";
      m += (count%3 == 2)?"</tr>":"";
      count++;
    }
    m += "</table>";
    div.innerHTML = (count!=0)?m:"<CENTER>No useable items in this category</CENTER>";
  },
  
  display_chest : function ()
  {
    var t = Tabs.Inventory;
    t.type = "chest";
    var div = document.getElementById("pbinventory");
    var count = 0;
    var m = "<TABLE>";
    m += "<TR><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='10px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='20px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td></tr><TR>";
    for (var k in t.chest){
      var item = t.chest[k];
      if(!item.name) continue;
      m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
      m += "<TD><input type=checkbox class='pbinv_chest' data-ft='"+JSON.stringify(item)+"' /></td>";
      m += "<TD><img width='20px' height='20px' src='https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+item.id+".jpg' /> "+item.name+"</td>";
      m += "<TD><input type=text size=3 id='pb_inv_chest_"+item.id+"' /></td>";
      m += "<TD>"+item.count+"</td>";
      m += (count%3 == 2)?"</tr>":"";
      count++;
    }
    m += "</table>";
    div.innerHTML = (count!=0)?m:"<CENTER>No useable items in this category</CENTER>";
  },
  
  display_court : function (){
    var t = Tabs.Inventory;
    t.type = "court";
    var div = document.getElementById("pbinventory");
    var count = 0;
    var m = "<TABLE>";
    m += "<TR><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='10px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td><TD width='20px'>&nbsp;</td><TD></td><TD>Name</td><TD>Use</td><TD>Count</td></tr><TR>";
    for (var k in t.court){
      var item = t.court[k];
      if(!item.name) continue;
      m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
      m += "<TD><input type=checkbox class='pbinv_court' data-ft='"+JSON.stringify(item)+"' /></td>";
      m += "<TD><img width='20px' height='20px' src='https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/items/70/"+item.id+".jpg' /> "+item.name+"</td>";
      m += "<TD><input type=text size=3 id='pb_inv_court_"+item.id+"' /></td>";
      m += "<TD>"+item.count+"</td>";
      m += (count%3 == 2)?"</tr>":"";
      count++;
    }
    m += "</table>";
    div.innerHTML = (count!=0)?m:"<CENTER>No useable items in this category</CENTER>";
  },
  
  start : function ()
  {
    var t = Tabs.Inventory;
    
    if(t.isBusy)
    {
      t.isBusy = false;
      $("pbinventory_start").value = "Start";
    } 
    else 
    {
      t.isBusy = true;
      
      $("pbinventory_start").value = "Stop";
      t.queue = [];
      $("pbinventory_info").innerHTML = "";
      var nodes = document.getElementsByClassName("pbinv_"+t.type);
      
      for(var i = 0; i < nodes.length; i++)
      {
        if(nodes[i].checked){
          try{
            t.queue.push(JSON.parse(nodes[i].getAttribute("data-ft")));
          } catch (e){
            logit(inspect(e,7,1));
          }
        }
      }
      
      if(t.queue.length > 0)
        t.nextqueue();
    }
  },
  
  nextqueue : function ()
  {
    var t = Tabs.Inventory;
    
    if(!t.isBusy)
      return;
    
    var div = $("pbinventory_info");
    var m = document.createElement('span');
    
    if(t.queue.length > 0)
    {
      var item = t.queue[0];
      t.counter = 0;
      t.max = parseIntNan($("pb_inv_"+t.type+"_"+item.id).value);
      m.innerHTML = "<span id='pb_inv_info_"+item.id+"'>Using item "+item.name+" <span id='pb_inv_info_count_"+item.id+"'>1</span> of <span id='pb_inv_info_max_"+item.id+"'>"+t.max+"</span>. Left <span id='pb_inv_info_left_"+item.id+"'>"+(t.max-t.counter)+"</span> <span id='pb_inv_info_extra_"+item.id+"'> </span></span><br />";
    } 
    else 
    {
      m.innerHTML = "Completed! \n";
      t.isBusy = false;
      $("pbinventory_start").value = "Start";
    }
    if(div.firstChild){
      div.insertBefore(m, div.firstChild);
    } else {
      div.appendChild(m);
    }
    t.useitem();
  },
  
  useitem : function ()
  {
    var t = Tabs.Inventory;
    if(!t.isBusy)
      return;
    var item = t.queue[0];
    unsafeWindow.cm.ItemController.use(item.id);
    setTimeout(t.wait, 250, 0);
  },
  
  wait : function (retries)
  {
    var t = Tabs.Inventory;
    
    if(!t.isBusy)
      return;
    
    var item = t.queue[0];
    // if(unsafeWindow.ksoItems[item.id].count == item.count && retries < 4){
      // $("pb_inv_info_extra_"+item.id).innerHTML = "Waiting.....";
      // retries++;
      // setTimeout(t.wait, 250, retries);
      // return;
    // }
    item = unsafeWindow.ksoItems[item.id];
    t.queue[0] = item;
    t.counter++;
    $("pb_inv_info_count_"+item.id).innerHTML = t.counter;
    $("pb_inv_info_left_"+item.id).innerHTML = (t.max-t.counter);
    
    if(t.counter >= t.max)
    {
      $("pb_inv_info_extra_"+item.id).innerHTML = "All done";
      t.queue.shift();
      t.nextqueue();
      return;
    }
    $("pb_inv_info_extra_"+item.id).innerHTML = "Done. Wait for 1 second..";
    setTimeout(t.useitem, 150);
  },
  
  show: function (){
  
  },
  hide: function (){
  
  }
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: ActionLog
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.ActionLog = {
  tabOrder: 130,
  tabLabel : 'Log',
  myDiv : null,
  logTab : null,
  maxEntries: 500,
  actionLog : [],
  state : null,
    
  init : function (div)
  {
    var t = Tabs.ActionLog;
    
    t.myDiv = div;
    t.myDiv.innerHTML = '<DIV class=pbStat>LOG - VERSION: '+ Version+'</div><DIV style="height:535px; max-height:535px; overflow-y:auto">\
      <TABLE cellpadding=0 cellspacing=0 id=pbactionlog class=pbTabLined><TR><TD></td><TD width=95%></td></table></div>';
    t.logTab = document.getElementById('pbactionlog');  
    t.state = 1;
    
    var a = JSON2.parse(GM_getValue ('log_'+getServerId(), '[]'));
    
    if (matTypeof(a) == 'array')
    {
      t.actionLog = a;
      
      for (var i=0; i<t.actionLog.length; i++)
      {
        t._addTab (t.actionLog[i].msg, t.actionLog[i].ts);
      }
    }
    
    window.addEventListener('unload', t.onUnload, false);
  },

  hide : function ()
  {
  },

  show : function ()
  {
  },

  onUnload : function ()
  {
    var t = Tabs.ActionLog;
    if (!ResetAll) GM_setValue ('log_'+getServerId(), JSON2.stringify(t.actionLog));
  },
    
  _addTab : function (msg, ts)
  {
    var t = Tabs.ActionLog;
    
    if (t.state != 1)
    {
      return;
    }
    
    if (t.logTab.rows.length >= t.maxEntries)
    {
      t.logTab.deleteRow(t.maxEntries - 1);
    }
    
    var row = t.logTab.insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = ts;
    row.insertCell(1).innerHTML = msg;
  },
  
  log : function (msg)
  {
    var t = Tabs.ActionLog;
    var ts = new Date().toTimeString().substring (0,8);
    
    t._addTab (msg, ts);
    
    while (t.actionLog.length >= 500)
    {
      t.actionLog.shift();
    }
    
    t.actionLog.push ({msg:msg, ts:ts});
  },
}

function actionLog (msg)
{
  if (!Tabs.ActionLog.tabDisabled)
  {
    Tabs.ActionLog.log (msg);
  }
}
    

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Options
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Options = {
  tabOrder: 699,
  myDiv : null,
  fixAvailable : {},

  init : function (div)
  {
    var t = Tabs.Options;
    t.myDiv = div;
    
    try {      
      m = '<DIV style="height:500px; max-height:500px; overflow-y:auto"><TABLE width=100% class=pbOptions cellspacing=0 cellpadding=0>\
        <TR><TD colspan=2><B>'+translate("Power Bot Config:")+'</b></td></tr>\
        <TR><TD><INPUT id=pballowWinMove type=checkbox /></td><TD>'+translate("Enable window drag (move window by dragging top bar with mouse)")+'</td></tr>\
        <TR><TD><INPUT id=pbTrackWinOpen type=checkbox /></td><TD>'+translate("Remember window open state on refresh")+'</td></tr>\
        <TR><TD><INPUT id=pbHideOnGoto type=checkbox /></td><TD>'+translate("Hide window when clicking on map coordinates")+'</td></tr>\
        <TR><TD><INPUT id=pbWideOpt type=checkbox '+ (GlobalOptions.pbWideScreen?'CHECKED ':'') +'/></td><TD>'+translate("Enable widescreen style:")+' '+ htmlSelector({normal:'Normal', wide:'Widescreen', ultra:'Ultra'},GlobalOptions.pbWideScreenStyle,'id=selectScreenMode') +' '+translate("(all domains, requires refresh)")+'</td></tr>\
        <TR><TD><INPUT id=pbsendmeaway type=checkbox '+ (GlobalOptions.pbNoMoreKabam?'CHECKED ':'')+'/></td><TD>'+translate("Send me away from kabam!")+'</td></tr>\
        <TR><TD>&nbsp;&nbsp;&nbsp;-</td><TD>'+translate("Change window transparency between \"0.7 - 2\" ")+'&nbsp <INPUT id=pbtogOpacity type=text size=3 /> <span style="color:#800; font-weight:bold"><sup>'+translate("*Requires Refresh")+'</sup></span></td></tr>\
        <TR><TD colspan=2><BR><B>'+translate("KofC Features:")+'</b></td></tr>\
        <TR><TD><INPUT id=pbFairie type=checkbox /></td><TD>'+translate("Disable all Fairie popup windows")+'</td></tr>\
        <TR><TD><INPUT id=pbWatchEnable type=checkbox '+ (GlobalOptions.pbWatchdog?'CHECKED ':'') +'/></td><TD>'+translate("Refresh if KOC not loaded within 1 minute (all domains)")+'</td></tr>\
        <TR><TD><INPUT id=pbEveryEnable type=checkbox /></td><TD>'+translate("Refresh KOC every")+' <INPUT id=pbeverymins type=text size=2 maxlength=3 \> '+translate("minutes")+'</td></tr>\
        <TR><TD><INPUT id=pbChatREnable type=checkbox /></td><TD>'+translate("Put chat on right (requires wide screen)")+'</td></tr>\
        <TR><TD><INPUT id=pbWMapEnable type=checkbox /></td><TD>'+translate("Use WideMap (requires wide screen)")+'</td></tr>\
        <TR><TD><INPUT id=pbGoldEnable type=checkbox /></td><TD>'+translate("Auto collect gold when happiness reaches")+' <INPUT id=pbgoldLimit type=text size=2 maxlength=3 \>%</td></tr>\
        <TR><TD><INPUT id=pbFoodToggle type=checkbox /></td><TD>'+translate("Enable Food Alert (On less then 6 Hours of food checked every hour)")+'</td></tr>\
        <TR><TD colspan=2><BR><B>'+translate("Extra Features")+':</b></td></tr>\
        <TR><TD><INPUT id=HelReq type=checkbox /></td><TD>'+translate("Help alliance build/research posts")+'</td></tr>\
        <TR><TD><INPUT id=DelReq type=checkbox /></td><TD>'+translate("Hide alliance requests in chat")+'</td></tr>\
        <TR><TD><INPUT id=PubReq type=checkbox '+ (GlobalOptions.autoPublishGamePopups?'CHECKED ':'') +'/></td><TD>'+translate("Auto publish Facebook posts for")+' '+ htmlSelector({0:'----', 80:'Everyone', 50:'Friends of Friends', 40:'Friends Only', 10:'Only Me'},GlobalOptions.autoPublishPrivacySetting,'id=selectprivacymode') +' '+translate("(For all domains)")+'<span style="color:#800; font-weight:bold"><sup>'+translate("*Only select ONE of these")+'</sup></span></td>\
        <TR><TD><INPUT id=cancelReq type=checkbox '+ (GlobalOptions.autoCancelGamePopups?'CHECKED ':'') + '/></td><TD>'+translate("Auto cancel Facebook posts")+'<span style="color:#800; font-weight:bold"><sup>'+translate("*Only select ONE of these")+'</sup></span></td>\
        <TR><TD><INPUT id=MapExtra type=checkbox /></td><TD>'+translate("Show Player & Might in map")+'.</td></tr>\
        <TR><TD><INPUT id=deletetoggle type=checkbox /></td><TD> '+translate("Auto delete barb/transport reports from you")+'</td></tr>\
        <TR><TD><INPUT id=deletes0toggle type=checkbox /></td><TD> '+translate("Auto delete transport reports to you")+'</td></tr>\
        <TR><TD><INPUT id=deletes1toggle type=checkbox /></td><TD> '+translate("Auto delete wild reports")+'</td></tr>\
        <TR><TD><INPUT id=deletes2toggle type=checkbox /></td><TD> '+translate("Auto delete crest target regardless of type")+'</td></tr>\
        <TR><TD><INPUT id=pbColorTab type=checkbox ' + (Options.colorCityTabs?'CHECKED ':'')+ '/></td><TD> Outline city tabs with defense status </td></tr>\
        <TR><TD colspan=2><BR><B>'+translate("Logging Options")+':</b></td></tr>\
        <TR><TD><INPUT id=logAutoCrest type=checkbox /></td><TD> '+translate("Log Auto Crest Messages")+'</td></tr>\
        <TR><TD><INPUT id=logAutoTrain type=checkbox /></td><TD> '+translate("Log Auto Train messages")+'</td></tr>\
        <TR><TD><INPUT id=logAutoTransport type=checkbox /></td><TD> '+translate("Log Auto Transport Messages")+'</td></tr>\
        <TR><TD colspan=2><BR><B>'+translate("Test Features")+':</b></td></tr>\
        <TR><TD><INPUT id=thronePresetButtons type=checkbox /></td><TD> '+translate("Enable Throne Preset Buttons")+'</td></tr>';
      m += '<TR><TD>&nbsp;&nbsp;&nbsp-</td><TD>'+strButton20(translate('Reset Captcha Timeout'), 'id=ResetCaptcha')+'</td></tr>\
        </table><BR><BR><HR>'+translate("Note that if a checkbox is greyed out there has probably been a change of KofC\'s code, rendering the option inoperable")+'.</div>';
      m += strButton20(translate('Reset ALL Options'), 'id=ResetALL');

      div.innerHTML = m;

      document.getElementById('selectScreenMode').addEventListener ('change', function()
      {
        GlobalOptions.pbWideScreenStyle = document.getElementById('selectScreenMode').value;
        GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));
      },false); 
      
      document.getElementById('selectprivacymode').addEventListener ('change', function()
      {
        GlobalOptions.autoPublishPrivacySetting = document.getElementById('selectprivacymode').value;
        GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));
      },false);
      
      document.getElementById('PubReq').addEventListener ('change', function()
      {
        GlobalOptions.autoPublishGamePopups = document.getElementById('PubReq').checked;
        GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));
      },false); 
      
      document.getElementById('cancelReq').addEventListener ('change', function()
      {
        GlobalOptions.autoCancelGamePopups = document.getElementById('cancelReq').checked;
        GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));
      },false); 

      document.getElementById('pbsendmeaway').addEventListener ('click', function()
      {
        GlobalOptions.pbNoMoreKabam = document.getElementById('pbsendmeaway').checked;
        GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));
      },false); 
      
      document.getElementById('ResetALL').addEventListener ('click', function()
      {
        var serverID = getServerId();
        RemoveList = (GM_listValues());

        for (i=0;i<RemoveList.length;i++)
        {
          logit(RemoveList[i]);
          GM_deleteValue(RemoveList[i]);
        }

        ResetAll=true;
        reloadKOC();
      },false);

      document.getElementById('ResetCaptcha').addEventListener ('click', function()
      {
        Options.captchaTimer = 0;
        checkCaptcha();
        saveOptions();
      },false);  

      document.getElementById('pbWatchEnable').addEventListener ('change', t.e_watchChanged, false);
      document.getElementById('pbWideOpt').addEventListener ('change', t.e_wideChanged, false);
      
      t.changeOpt ('pbtogOpacity', 'Opacity');
      t.togOpt ('pballowWinMove', 'pbWinDrag', mainPop.setEnableDrag);
      t.togOpt ('pbTrackWinOpen', 'pbTrackOpen');
      t.togOpt ('pbHideOnGoto', 'hideOnGoto');
      t.togOpt ('pbFairie', 'pbKillFairie', FairieKiller.setEnable);
      t.togOpt ('pbGoldEnable', 'pbGoldEnable', CollectGold.setEnable);
      t.changeOpt ('pbgoldLimit', 'pbGoldHappy');
      t.togOpt ('pbFoodToggle', 'pbFoodAlert');
      t.changeOpt ('pbeverymins', 'pbEveryMins' , RefreshEvery.setTimer);
      t.togOpt ('pbEveryEnable', 'pbEveryEnable', RefreshEvery.setEnable);
      t.togOpt ('pbChatREnable', 'pbChatOnRight', WideScreen.setChatOnRight);
      t.togOpt ('pbWMapEnable', 'pbWideMap', WideScreen.useWideMap);
      t.togOpt ('pbEveryEnable', 'pbEveryEnable', RefreshEvery.setEnable);
      t.togOpt ('HelReq', 'HelpRequest');
      t.togOpt ('DelReq', 'DeleteRequest');
      t.togOpt ('MapExtra', 'MapShowExtra');
      t.togOpt ('pbColorTab', 'colorCityTabs', Tabs.tower.cityBtnColor);
      t.togOpt ('deletetoggle', 'DeleteMsg');
      t.togOpt ('deletes0toggle', 'DeleteMsgs0');
      t.togOpt ('logAutoCrest', 'logAutoCrest');
      t.togOpt ('thronePresetButtons', 'thronePresetButtons');
      t.togOpt ('logAutoTrain', 'logAutoTrain');
      t.togOpt ('logAutoTransport', 'logAutoTransport');
      t.togOpt ('deletes1toggle', 'DeleteMsgs1');
      t.togOpt ('deletes2toggle', 'DeleteMsgs2');     
      // t.togOpt ('shortMarchDelayToggle', 'shortNonMarchDelay');  
      // t.togOpt ('newSalvage', 'useNewSalvage');      
    } 
    catch (e) 
    {
      div.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }      
  },

  hide : function ()
  {
  },

  show : function ()
  {
  },

  togOpt : function (checkboxId, optionName, callOnChange)
  {
    var t = Tabs.Options;
    var checkbox = document.getElementById(checkboxId);
    
    if (Options[optionName])
      checkbox.checked = true;
    
    checkbox.addEventListener ('change', eventHandler, false);
    
    function eventHandler ()
    {
      Options[optionName] = this.checked;
      saveOptions();
      
      if (callOnChange)
        callOnChange (this.checked);
    }
  },
  
  changeOpt : function (valueId, optionName, callOnChange)
  {
    var t = Tabs.Options;
    var e = document.getElementById(valueId);
    e.value = Options[optionName];
    e.addEventListener ('change', eventHandler, false);
    
    function eventHandler ()
    {
      Options[optionName] = this.value;
      saveOptions();
      
      if (callOnChange)
        callOnChange (this.value);
    }
  },
  
  e_watchChanged : function ()
  {
    GlobalOptions.pbWatchdog = document.getElementById('pbWatchEnable').checked;
    GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));  
  },
  
  e_wideChanged : function ()
  {
    GlobalOptions.pbWideScreen = document.getElementById('pbWideOpt').checked;
    GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));  
  },
  
  e_updateChanged : function ()
  {
  },
  
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Reassign
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Reassign = 
{
  tabOrder: 30,
  tabLabel: 'Reassign',
  myDiv: null,
  timer: null,
  reassignState: [],
  lRE: [],
  reassignRoutes: [],
  count:0,
  check:false,
  troopsselect: ["SupplyTroop", "Militiaman", "Scout", "Pikeman", "Swordsman", "Archers", "Cavalry", "HeavyCavalry", "SupplyWagons", "Ballista", "BatteringRam", "Catapult", "BloodThorn", "Executioner", "SiegeWall"],

  init: function(div)
  {
    var t = Tabs.Reassign;
    t.myDiv = div;

    t.reassignState = 
    {
      running: false,
    };

    t.readReassignState();
    t.readReassignRoutes();
    t.e_reassignRoutes();

    var m = '<DIV id=pbReMainDivF class=pbStat>'+translate("AUTOMATED REASSIGN FUNCTION")+'</div><TABLE id=pbtraderfunctions width=100% height=0% class=pbTab><TR align="center">';

    if (t.reassignState.running == false) 
    {
      m += '<TD><INPUT id=pbReassignState type=submit value="Reassign = OFF"></td>';
    } 
    else 
    {
      m += '<TD><INPUT id=pbReassignState type=submit value="Reassign = ON"></td>';
    }

    m += '<TD><INPUT id=pbReassShowRoutes type=submit value="Show Routes"></td>';
    m += '</tr></table></div>';
    m += '<DIV id=pbReassignDivD class=pbStat>'+translate("ADD REASSIGN ROUTE")+'</div>';

    m += '<TABLE id=pbaddreasignroute width=95% height=0% class=pbTab><TR align="left">';
    m += '<TD width=20px>'+translate("From City:")+'</td> <TD width=310px><DIV style="margin-bottom:10px;"><span id=ptassigncity></span></div></td></tr>';

    m += '<TR align="left">';
    m += '<TD width=20px>'+translate("To City:")+'</td> <TD width=310px><DIV style="margin-bottom:10px;"><span id=ptassigncityTo></span></div></td>';
  
    m += '<TR align="left">';
    m += '<TD colspan=4>'+translate("Time inbetween to check reassign:")+' <INPUT id=pbreassigninterval type=text size=2 value="'+Options.reassigninterval+'"\> '+translate("minutes")+'</td></tr>';
    m += '<TR><TD><INPUT id=autofilloff type=checkbox unchecked=true\> '+translate("Lock troop values")+'</TR></TD></table>';
    m += '<DIV style="margin-top:10px;margin-bottom:5px;">'+translate("Fill in the number of troops you want to keep in a city:")+'</div>';
    m += '<TABLE id=pbaddreasignroute width=100% height=0% class=pbTab><TR align="center">';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_50.jpg?6545"></td>';
    m += '<TD>'+translate("Supply Troop")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_50.jpg?6545"></td>'
    m += '<TD>'+translate("Militiaman")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_50.jpg?6545"></td>'
    m += '<TD>'+translate("Scout")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_50.jpg?6545"></td>'
    m += '<TD>'+translate("Pikeman")+'</td></tr>'
    m += '<TR><TD><INPUT id=pbSupplyTroops type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetSupplyTroops disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbMilitiaman type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetMilitiaman disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbScout type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetScout disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbPikeman type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetPikeman disabled=true type=text size=10 maxlength=10 value="0"\></td></tr>';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_50.jpg?6545"></td>';
    m += '<TD>'+translate("Swordsman")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_50.jpg?6545"></td>'
    m += '<TD>'+translate("Archer")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_50.jpg?6545"></td>'
    m += '<TD>'+translate("Cavalry")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_50.jpg?6545"></td>'
    m += '<TD>'+translate("Heavy Cavalry")+'</td></tr>'
    m += '<TR><TD><INPUT id=pbSwordsman type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetSwordsman disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbArcher type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetArcher disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbCavalry type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetCavalry disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbHeavyCavalry type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetHeavyCavalry disabled=true type=text size=10 maxlength=10 value="0"\></td></tr>';
    
    m += '<TR><TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_50.jpg?6545"></td>';
    m += '<TD>'+translate("Supply Wagon")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_50.jpg?6545"></td>'
    m += '<TD>'+translate("Ballista")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_50.jpg?6545"></td>'
    m += '<TD>'+translate("Battering Ram")+'</td>'
    m += '<TD rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_50.jpg?6545"></td>'
    m += '<TD>'+translate("Catapult")+'</td></tr>'
    m += '<TR><TD><INPUT id=pbSupplyWagon type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetSupplyWagon disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbBallista type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetBallista disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbBatteringRam type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetBatteringRam disabled=true type=text size=10 maxlength=10 value="0"\></td>';
    m += '<TD><INPUT id=pbCatapult type=checkbox unchecked=true\>';
    m += '<INPUT id=pbtargetCatapult disabled=true type=text size=10 maxlength=10 value="0"\></td></tr></table>';
    
    m += '<DIV style="text-align:center; margin-top:15px"><INPUT id=pbSaveRouteReassign type=submit value="'+translate("Add Route")+'"></div>';
    
    t.myDiv.innerHTML = m;
    
    t.tcp = new CdispCityPicker ('ptreassign', document.getElementById('ptassigncity'), true, null, 0);
    t.tcpto = new CdispCityPicker ('ptreassignTo', document.getElementById('ptassigncityTo'), true);

    var k;
    
    for(k in troopTypes)
    {
      logit("Reassign: Set troop count [(" + k + ") " + troopTypes[k] + "]");
      jQuery('#pbtarget'+troopTypes[k]).val(parseInt(Seed.units['city' + t.tcp.city.id]['unt'+k]));
    }

    jQuery('#ptassigncity').click(function()
    {
      if(jQuery('#autofilloff:checked').length == 0)
      {
        for(var k in troopTypes) 
        {
          jQuery('#pbtarget'+troopTypes[k]).val(parseInt(Seed.units['city' + t.tcp.city.id]['unt'+k]));
        }
      }
    });
    
    document.getElementById('pbReassignState').addEventListener('click', function()
    {
      t.toggleReassignState(this);
    }, false);
    
    document.getElementById('pbSaveRouteReassign').addEventListener('click', function()
    {
      t.addReassignRoute();
    }, false);
    
    document.getElementById('pbReassShowRoutes').addEventListener('click', function()
    {
      t.showReassignRoutes();
    }, false);
    
    document.getElementById('pbreassigninterval').addEventListener('keyup', function()
    {
      if (isNaN(document.getElementById('pbreassigninterval').value))
      { 
        document.getElementById('pbreassigninterval').value=0 ;
      }

      Options.reassigninterval = document.getElementById('pbreassigninterval').value;
      saveOptions();
    }, false);
    
    var k;
    
    for(var k in troopTypes)
    {
      jQuery('#pbtarget' + troopTypes[k]).keyup( function(event)
      {
        logit("Reassign: - keyup" + this.value);
        if (isNaN(this.value)) 
        { 
          this.value = 0 ;
        }
      });
    }
     
    function configureInput(troopType) 
    {
      if(document.getElementById('pb' + troopType)) 
      {
        document.getElementById('pb' + troopType).addEventListener('click', function() 
        {
          if (document.getElementById('pb' + troopType).checked==false) 
          {
            document.getElementById('pbtarget' + troopType).disabled = true;
          }
          else 
          {
            document.getElementById('pbtarget' + troopType).disabled = false;
          }
        },false);
      }
    }
     
    for(var k in troopTypes)
    {
      configureInput(troopTypes[k])
    }

    window.addEventListener('unload', t.onUnload, false);
  },
    
  e_reassignRoutes: function()
  {
    var t = Tabs.Reassign;
    var now = new Date();
    
    if (t.reassignState.running == true)    
    {
      var now = new Date().getTime() / 1000.0;
      now = now.toFixed(0);
      var last = Options.lastreassign;

      if ( now > (parseInt(last) + (Options.reassigninterval * 60)))
      {
        t.checkdoReassign();
        Options.lastreassign = now;
        saveOptions();
      }
    }
    
    setTimeout(function(){ t.e_reassignRoutes();}, 60 * 1000);
  },
      
  delReassignRoutes: function() 
  {
    var t = Tabs.Reassign;
    t.reassignRoutes= [];
  },

  checkcoords : function (obj)
  {
    var t = Tabs.Reassign;
    if(obj.id == 'pbok')
    {
      t.check = true;
      t.addReassignRoute();
    }
    return;     
  },

  addReassignRoute: function () 
  {
    var t = Tabs.Reassign;
    var city = t.tcp.city.id;

    if(t.tcpto.city == null)
    {
      new CdialogCancelContinue('<SPAN class=boldRed>'+translate("No destination selected!")+'</span>', null, null, mainPop.getMainDiv);
      return;
    }

    if(t.tcp.city.id == t.tcpto.city.id)
    {
      new CdialogCancelContinue('<SPAN class=boldRed>'+translate("Can\'t reassign to same city!")+'</span>', null, null, mainPop.getMainDiv);
      return;
    }
    
    if ((t.tcpto.city.x == 0 && t.tcpto.city.y == 0)&& !t.check)
    {
      new CdialogConfirm ('<SPAN class=boldRed>'+translate("You are about to set a route to location 0,0!")+'</span>', t.checkcoords, unsafeWindow.modal_attack_check, mainPop.getMainDiv); 
      return;
    }
    
    t.check = false;
    
    var SendSupplyTroop = document.getElementById('pbSupplyTroops').checked;
    var SendMilitiaman = document.getElementById('pbMilitiaman').checked;
    var SendScout = document.getElementById('pbScout').checked;
    var SendPikeman = document.getElementById('pbPikeman').checked;
    var SendSwordsman = document.getElementById('pbSwordsman').checked;
    var SendArchers = document.getElementById('pbArcher').checked;
    var SendCavalry = document.getElementById('pbCavalry').checked;
    var SendHeavyCavalry = document.getElementById('pbHeavyCavalry').checked;
    var SendSupplyWagons = document.getElementById('pbSupplyWagon').checked;
    var SendBallista = document.getElementById('pbBallista').checked;
    var SendBatteringRam = document.getElementById('pbBatteringRam').checked;
    var SendCatapult = document.getElementById('pbCatapult').checked;
    
    var SupplyTroop = document.getElementById('pbtargetSupplyTroops').value;
    var Militiaman = document.getElementById('pbtargetMilitiaman').value;
    var Scout = document.getElementById('pbtargetScout').value;
    var Pikeman = document.getElementById('pbtargetPikeman').value;
    var Swordsman = document.getElementById('pbtargetSwordsman').value;
    var Archers = document.getElementById('pbtargetArcher').value;
    var Cavalry = document.getElementById('pbtargetCavalry').value;
    var HeavyCavalry = document.getElementById('pbtargetHeavyCavalry').value;
    var SupplyWagons = document.getElementById('pbtargetSupplyWagon').value;
    var Ballista = document.getElementById('pbtargetBallista').value;
    var BatteringRam = document.getElementById('pbtargetBatteringRam').value;
    var Catapult = document.getElementById('pbtargetCatapult').value;
    var target_x = t.tcpto.city.x;
    var target_y = t.tcpto.city.y;
    var target_city = t.tcpto.city.id;
        
    var lRE = t.reassignRoutes;
    lRE.push(
    {
      city:       city,
      target_x:     target_x,
      target_y:     target_y,
      target_city:        target_city,
      SendSupplyTroop:  SendSupplyTroop,
      SupplyTroop:    SupplyTroop,
      SendMilitiaman:   SendMilitiaman,
      Militiaman:     Militiaman,
      SendScout:      SendScout,
      Scout:        Scout,
      SendPikeman:    SendPikeman,
      Pikeman:      Pikeman,
      SendSwordsman:    SendSwordsman,
      Swordsman:      Swordsman,
      SendArchers:    SendArchers,
      Archers:      Archers,
      SendCavalry:    SendCavalry,
      Cavalry:      Cavalry,
      SendHeavyCavalry: SendHeavyCavalry,
      HeavyCavalry:   HeavyCavalry,
      SendSupplyWagons: SendSupplyWagons,
      SupplyWagons:   SupplyWagons,
      SendBallista:     SendBallista,
      Ballista:       Ballista,
      SendBatteringRam: SendBatteringRam,
      BatteringRam:   BatteringRam,
      SendCatapult:   SendCatapult,
      Catapult:     Catapult,
    });
    
    document.getElementById('pbReassignDivD').style.background ='#99FF99';
    setTimeout(function(){ (document.getElementById('pbReassignDivD').style.background =''); }, 1000);
  },

  showReassignRoutes: function () 
  {
    var t = Tabs.Reassign;
    var popReassignRoutes = null;
    t.popReassignRoutes = new pbPopup('pbShowTrade', 0, 0, 1100, 485, true, function() {clearTimeout (1000);});
    var m = '<DIV style="overflow-y:auto"><TABLE align=center class="pbReassign" id="pbRoutesQueue">';       
    t.popReassignRoutes.getMainDiv().innerHTML = '</table></div>' + m;
    t.popReassignRoutes.getTopDiv().innerHTML = '<TD><CENTER><B>'+translate("Reassign routes")+'</center></td>';
    t.paintReassignRoutes();
    t._addTabHeader();
    t.popReassignRoutes.autoWidth(true);
    t.popReassignRoutes.autoHeight(true);
    t.popReassignRoutes.show(true)  ;
  },

  paintReassignRoutes: function()
  {
    var t = Tabs.Reassign;
    var r = t.reassignRoutes;
    var cityname;

    for (var i = (r.length-1); i>=0; i--) 
    {
      for (var y=0; y< Seed.cities.length;y++) 
      {
        if ( parseInt(Seed.cities[y][0]) == r[i].city) 
        {
          var cityname = Seed.cities[y][1];
        }
      }    
      var queueId = i;
      t._addTab(queueId,cityname, r[i]);
    }
  },
    
  _addTab: function(queueId,cityname,route)
  {
    var t = Tabs.Reassign;
    var To = route.target_x + ',' + route.target_y;
  
    for (var y = 0; y < Seed.cities.length;y++) 
    {
      if ( parseInt(Seed.cities[y][0]) == parseInt(route.target_city))
      {
        To = Seed.cities[y][1];
        break;
      }
    } 
    
    var row = document.getElementById('pbRoutesQueue').insertRow(0);
    var rowNumber = 0;
    row.vAlign = 'top';
    row.insertCell(rowNumber++).innerHTML = queueId;
    row.insertCell(rowNumber++).innerHTML = cityname;
    row.insertCell(rowNumber++).innerHTML = To;
    
    var unitNumber = 1;
    for(unit in unsafeWindow.unitcost)
    {
      if(route["Send" + troopTypes[unitNumber]])
      {
        row.insertCell(rowNumber++).innerHTML = route[troopTypes[unitNumber]];
      }
      else
      {
        row.insertCell(rowNumber++).innerHTML = "------";
      }
      unitNumber++;
    }
    row.insertCell(rowNumber++).innerHTML = '<a class="button20" id="tradeedit_' + queueId + '"><span>'+translate("Edit")+'</span></a><a class="button20" id="tradecancel_' + queueId + '"><span>'+translate("Delete")+'</span></a>';

    document.getElementById('tradecancel_' + queueId).addEventListener('click', function() 
    {
      t.cancelQueueElement(queueId);
    }, false);
    
    document.getElementById('tradeedit_' + queueId).addEventListener('click', function() 
    {
      t.editQueueElement(queueId);
    }, false);
  },
   
  _addTabHeader: function() 
  {
    var t = Tabs.transport;
    var row = document.getElementById('pbRoutesQueue').insertRow(0);

    rowNumber = 0;
    row.vAlign = 'top';
    row.insertCell(rowNumber++).innerHTML = "ID";
    row.insertCell(rowNumber++).innerHTML = translate("From");
    row.insertCell(rowNumber++).innerHTML = translate("To");
    
    for(unit in unsafeWindow.unitcost)
    {
      row.insertCell(rowNumber++).innerHTML = unsafeWindow.unitcost[unit][0];
    }
    row.insertCell(rowNumber++).innerHTML = translate("Delete");
  },   
     
  cancelQueueElement: function(queueId)
  {
    var t = Tabs.Reassign;
    var queueId = parseInt(queueId);
    t.reassignRoutes.splice(queueId, 1);
    t.showReassignRoutes();
  },
     
  editQueueElement: function(queueId) 
  {
    var t = Tabs.Reassign;
    var r = t.reassignRoutes;
    var popEditReassignRoute = null;
    
    t.popEditReassignRoute = new pbPopup('pbEditReassign', 0, 0, 700, 300, true, function() {clearTimeout (1000);});
    var m = "";
    
    m += '<DIV style="max-height:295px; height:295px; overflow-y:auto">';
    m +='<TABLE align=center cellpadding=3 cellspacing=4 width=100% class=pbTab id="pbRouteEdit">'; 

    var row = 0;
    
    for (k = 0; k < (t.troopsselect.length * 2); k++) 
    {
      if((k % 4)  == 0) 
      {
        m += '<tr>';
      }
      
      var unit = Math.floor(k - (4 * Math.floor((row + 1) / 2) ));
      
      if((row % 2) == 0) 
      {
        m += '<td rowspan="2"><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_' + (unit + 1) + '_30.jpg?6545"></td>';
        m += '<td>'+ t.troopsselect[unit] + '</td>';
      } 
      else 
      {
        var troopCount = r[queueId][t.troopsselect[unit]] || 0;
        m += '<td><INPUT id=pbEditReassignEnable_' + t.troopsselect[unit] + ' type=checkbox '+ (r[queueId]["Send"+t.troopsselect[unit]]?' CHECKED':'') + '\>';
        m += '<input id=pbEditReassignCount_' + t.troopsselect[unit] + ' type=text size=7 maxlength=6 value='+ troopCount +' \></td>';
      }
      
      if((k % 4)  == 3) 
      {
        m += '</tr>';
        row++;
      }
    }
    
    m+= '<tr><td colspan="8" align=center><a class="button20" id="pbReassignEditSave"><span>'+translate("Save")+'</span></a></td></tr>';
    
    t.popEditReassignRoute.getMainDiv().innerHTML = '</table></div>' + m;
    t.popEditReassignRoute.getTopDiv().innerHTML = '<TD><CENTER><B>'+translate("Edit route")+'</center></td>';
    t.popEditReassignRoute.show(true) ;

    jQuery("[id^=pbEditReassignCount_]").keyup(function(event) 
    { 
      if (isNaN(this.value)) 
      { 
        this.value=0 ;
      }
    });
    
    document.getElementById('pbReassignEditSave').addEventListener('click', function() 
    {
      t.saveEditQueueElement(queueId);
      t.popEditReassignRoute.show(false);
      t.showReassignRoutes();
    }, false);
  },
  
  saveEditQueueElement: function(queueId) 
  {
    var t = Tabs.Reassign;
    var r = t.reassignRoutes;
    
    jQuery("[id^=pbEditReassignEnable_]").each(function(index) 
    { 
      var enable = this.id.split("_");
      r[queueId]["Send" + enable[1]] = this.checked; 
    });
    
    jQuery("[id^=pbEditReassignCount_]").each(function(index) 
    { 
      var troopCount = this.id.split("_");
      r[queueId][troopCount[1]] = this.value; 
    });
    
    t.saveReassignRoutes();
  },
  
  saveReassignRoutes: function()
  {
    var t = Tabs.Reassign;
    var serverID = getServerId();
    GM_setValue('reassignRoutes_' + serverID, JSON2.stringify(t.reassignRoutes));
  },

  readReassignRoutes: function()
  {
    var t = Tabs.Reassign;
    var serverID = getServerId();
    s = GM_getValue('reassignRoutes_' + serverID);
    
    if (s != null) 
    {
      route = JSON2.parse(s);
      for (k in route)
      {
        t.reassignRoutes[k] = route[k];
      }
    }
    
    t.checkcitymoved();
  },

  checkcitymoved: function()
  {
    var t = Tabs.Reassign;
    
    for(var i=0; i < t.reassignRoutes.length; i++)
    {
      if(typeof t.reassignRoutes[i].target_city == 'undefined')
        continue;
      if(t.reassignRoutes[i].target_x != Cities.byID[t.reassignRoutes[i].target_city].x)
        t.reassignRoutes[i].target_x = Cities.byID[t.reassignRoutes[i].target_city].x;
      if(t.reassignRoutes[i].target_y != Cities.byID[t.reassignRoutes[i].target_city].y)
        t.reassignRoutes[i].target_y = Cities.byID[t.reassignRoutes[i].target_city].y;
    }
  },

  saveReassignState: function()
  {
    var t = Tabs.Reassign;
    var serverID = getServerId();
    GM_setValue('reassignState_' + serverID, JSON2.stringify(t.reassignState));
  },

  readReassignState: function()
  {
    var t = Tabs.Reassign;
    var serverID = getServerId();
    s = GM_getValue('reassignState_' + serverID);
    
    if (s != null) 
    {
      state = JSON2.parse(s);
      for (k in state)
        t.reassignState[k] = state[k];
    }
  },

  toggleReassignState: function(obj)
  {
    var t = Tabs.Reassign;
    if (t.reassignState.running == true) 
    {
      t.reassignState.running = false;
      obj.value = "Reassign = OFF";
      t.checkdoreassigntimeout = null;
      t.count = 0;
    } 
    else 
    {
      t.reassignState.running = true;
      obj.value = "Reassign = ON";
      t.e_reassignRoutes();
    }
  },
  
  checkdoReassign: function()
  {
    var t = Tabs.Reassign;
    t.doReassign(t.count);
    t.count++;

    if(t.count < t.reassignRoutes.length && t.reassignState.running)
    {
      t.checkdoreassigntimeout = setTimeout(function() { t.checkdoReassign();}, 5000);
    } 
    else 
    {
      logit("Reassign: cycle complete");
      t.count = 0;
    }
  },
    
  doReassign: function(count)
  {
    var t = Tabs.Reassign;
    var city = t.reassignRoutes[count]["city"];

    if (t.reassignRoutes.length == 0) 
    {
      logit("Reassign: no actions remaining");
      return;
    }

    var cityID = 'city' + city;

    if(!Cities.byID[city]) 
    {
      logit("Reassign: not a valid city id");
      return;
    }

    var send=[];
    var citytotal=0;
    var totalsend=0;
    var city = t.reassignRoutes[count]["city"];
    var xcoord = t.reassignRoutes[count]["target_x"];
    var ycoord = t.reassignRoutes[count]["target_y"];
    var maxsend = getMaxMarchSize(cityID);

    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

    for(unit = 1 ; unit <= 12 ; unit++) 
    {
      params["u" + unit] = 0;
    }

    for (k = 0; k < t.troopsselect.length; k++) 
    {
      var troopType = (parseInt(k) + 1);
      var citytroops = Seed.units[cityID]['unt' + troopType];

      if(t.reassignRoutes[count]['Send'+t.troopsselect[k]] == false) 
      { 
        continue; 
      }

      if(citytroops > t.reassignRoutes[count][t.troopsselect[k]]) {
        var sendtroops = parseInt(citytroops) - parseInt(t.reassignRoutes[count][t.troopsselect[k]]);

        if (parseInt(sendtroops) < 0) {
          sendtroops = 0;
        }

        send[troopType] = sendtroops;
        totalsend += send[troopType];
      }

      if(totalsend > maxsend){
        totalsend -= send[troopType];
        send[troopType] = parseInt(maxsend - totalsend);
        totalsend += send[troopType];
        break;
      }
    }

    for (var t = 0 ; t < Seed.cities.length ; t++) 
    {
      if ( parseInt(Seed.cities[t][0]) == city) var cityname = Seed.cities[t][1];
    }

    params.cid = city;
    params.type = "5";
    params.kid = 0;
    params.xcoord = xcoord;
    params.ycoord = ycoord;

    for(unit = 1 ; unit <= 12 ; unit++) 
    {
      params["u" + unit] = send[unit];
    }

    if (totalsend > 0) 
    {
      
      logit("Reassign: sending request");
      
      _ajaxCall = function()
      {
        var profiler = new CM.Profiler("ResponseTime", "march.php");
        
        new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
        {
          method: "post",
          parameters: params,
          loading: true,
          onSuccess: function (transport) 
          {
            profiler.stop();
            var rslt = eval("(" + transport.responseText + ")");
            
            if (rslt.ok) 
            {
              actionLog('Reassign: From: ' + cityname + ", To: " + xcoord + ',' + ycoord + " -> Troops: " + totalsend);
              addOutgoingMarch(params, rslt);
              
              CheckUpdateSeed(rslt);
            } 
            else 
            {
              if (rslt.user_action) 
              {
                var user_action = 
                {
                  marchWarning: function() 
                  {
                    logit('Captcha: [reassign] captcha warning');
                    actionLog('Captcha: [reassign] captcha warning');
                  },
                  marchCaptcha: function() 
                  {
                    actionLog('Captcha: [reassign] triggered captcha');
                    logit('Captcha: [reassign] triggered captcha');
                    startCaptcha();
                  },
                  backOffWaitTime: function() 
                  {
                    logit('Captcha: [reassign] back off time - ' + rslt.wait_time);
                    actionLog('Captcha: [reassign] back off time - ' + rslt.wait_time);
                    params.tt = rslt.tt;
                    setTimeout(_ajaxCall, rslt.wait_time * 1000)
                  }
                };
                user_action[rslt.user_action].call();
              }
              else
              {
                actionLog('Reassign: failure' + cityname + ' - ' + rslt.error_code + ' -  ' + rslt.msg + ' -  ' + rslt.feedback);
              }
            }
          },
          
          onFailure: function () 
          {
            profiler.stop();  
          }
        }, true);
      };
      _ajaxCall();
    } else {
      logit("Reassign: no troops to send");
    }
  },
  
  show: function(){
    var t = Tabs.Reassign;
  },
    
  hide: function(){
    var t = Tabs.Reassign;
  },

  onUnload: function()
  {
    var t = Tabs.Reassign;

    if (!ResetAll) 
    {
      t.saveReassignRoutes();
    }
    
    if (!ResetAll) 
    {
      t.saveReassignState();
    }
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Autotrain
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.AutoTrain = {
  tabOrder: 120,
  tabLabel: 'Train',
  myDiv: null,
  city:0,
  gamble : {"1":{"min":"5","max":"15","cost":"2"},"2":{"min":"10","max":"25","cost":"4"}},
  
  init: function(div)
  {
    var t = Tabs.AutoTrain;
    t.myDiv = div;
    t.city = 0;
    t.nextcity();
  
    var m = '';
    m += '<DIV class=pbStat>AUTO TRAIN</div><TABLE width=100% height=0% class=pbTab><TR><TD width=200></td>';
    m += '<TD align=center><INPUT id=pbAutoTrainState type=submit value="'+translate("AutoTrain")+' = '+ (TrainOptions.Running?'ON':'OFF')+'"></td>';
    m += '<TD align=right><INPUT id=pbShowTrainHelp type=submit value='+translate("HELP")+'></td>';
    m += '</tr></table>';
    m += '<table>';
    m += '<TR><TD align=right>'+translate("Only train when throne room preset set")+': <SELECT id=pbTrainPresetCraftLimitPreset type=list></select></td></tr>';
    m += '</table>';
    m += '<DIV class=pbStat>TRAIN OPTIONS</div><TABLE width=100% height=0% class=pbTab><TR align="center">';

    for (i=0;i<Seed.cities.length;i++)
    {
      var citynum = Seed.cities[i][0];
      city = i+1;
      m += '<TABLE width=100% height=0% class=pbTab><TR align="left">';
      m += '<TR><TD width=30px><INPUT type=checkbox class='+city+' id="SelectCity'+city+'"></td>';
      m += '<TD><TABLE><TR>';
      m += '<TD><B>'+ Seed.cities[i][1] +'</b></td>';
      m += '<TD width=150px><SELECT class='+city+' id="TroopsCity'+city+'"><option value="Select">--Select--</options>';
      
      for (y in unsafeWindow.unitcost) 
      {
        var faux = 0;
        var uc = unsafeWindow.unitcost[y];
        
        if (matTypeof(uc[8]) == 'object')
        {
          if(!Seed.cityData.city[citynum].isPrestigeCity) 
          {
            for (k in uc[8])
            {
              var b = getCityBuilding (Seed.cities[i][0], k.substr(1));
              if (b.maxLevel < uc[8][k][1])
              {
                faux = 1;
                break;
              }
            }
          }
          else 
          {
            if(uc[8]['b13']) 
            {
              var b = getCityBuilding (Seed.cities[i][0], 13);
              if (b.maxLevel < uc[8]['b13'][1])
              {
                faux = 1;
              }
            }
          } 
        }
        
        if (matTypeof(uc[9]) == 'object')
        {
          for (k in uc[9])
          {
            if (parseInt(Seed.tech['tch'+k.substr(1)]) < uc[9][k][1])
            {
              faux = 1;
              break;
            }
          }
        }
        
        if(y == "unt13") faux = 1;
        if(y == "unt14") faux = 1;
        if(y == "unt15") faux = 1;
        
        if (faux==0)
        {
            m+='<option value="'+y.substr(3)+'">'+unsafeWindow.unitcost[y][0]+'</option>';
        }
      }

      m += '</select></td>';
      m += '<TD width=100px>Min.: <INPUT class='+city+' id=treshold'+city+' type=text size=4 maxlength=6 value="'+ TrainOptions.Threshold[city]+'"\></td>';
      m += '<TD width=130px><INPUT type=checkbox class='+city+' id="SelectMax'+city+'"> '+translate("Max")+'.: <INPUT class='+city+' id=max'+city+' type=text size=5 maxlength=6 value="'+ TrainOptions.Max[city]+'"\></td>';
      m += '<TD>'+translate("Use Workers")+': ';
      m += '<SELECT class='+city+' id="workers'+city+'"><option value="0">0%</options>';
      m += '<option value="25">25%</options>';
      m += '<option value="50">50%</options>';
      m += '<option value="75">75%</options>';
      m += '<option value="100">100%</options></select>';
      m += '</td><td>';
      m += '<TD><SELECT class='+city+' id="TrainSpeedItem_'+city+'">\
            <option value=0><CENTER>--- '+unsafeWindow.g_js_strings.commonstr.items+' '+unsafeWindow.g_js_strings.commonstr.speedup+' ---</center></option>\
            <option value=36>'+unsafeWindow.itemlist.i36.name+'</option>\
            <option value=37>'+unsafeWindow.itemlist.i37.name+'</option>\
            <option value=38>'+unsafeWindow.itemlist.i38.name+'</option></select>';
      m += '</td></tr></table></td><tr>';
      m += '<TD></td><TD><TABLE><TR>';
      m += '<TD width=5%><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/food_30.png"></td>';
      m += '<TD><INPUT class='+city+' id="KeepFood'+city+'" type=text size=7 maxlength=7 value="'+ TrainOptions.Keep[city]['Food']+'"\></td>';
      m += '<TD width=20px><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/wood_30.png"></td>';
      m += '<TD><INPUT class='+city+' id="KeepWood'+city+'" type=text size=7 maxlength=7 value="'+ TrainOptions.Keep[city]['Wood']+'"\></td>';
      m += '<TD width=20px><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/stone_30.png"></td>';
      m += '<TD><INPUT class='+city+' id="KeepStone'+city+'" type=text size=7 maxlength=7 value="'+ TrainOptions.Keep[city]['Stone']+'"\></td>';
      m += '<TD width=20px><img src="http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/iron_30.png"></td>';
      m += '<TD><INPUT class='+city+' id="KeepOre'+city+'" type=text size=7 maxlength=7 value="'+ TrainOptions.Keep[city]['Ore']+'"\></td>';
      m += '<TD><SELECT class='+city+' id="Resource'+city+'"><option value="true">'+translate("Keep")+'</options>';
      m += '<option value="false">'+translate("Use")+'</option>';
      m += '</select></td>';
        
      m += '<TD><SELECT class='+city+' id="TrainSpeed_'+city+'">\
            <option value=0><CENTER>--- '+unsafeWindow.g_js_strings.commonstr.speedup+' ---</center></option>\
            <option value=1>'+ t.gamble[1].cost+'x res ('+ t.gamble[1].min+' - '+t.gamble[1].max+'%)</option>\
            <option value=2>'+ t.gamble[2].cost+'x res ('+ t.gamble[2].min+' - '+t.gamble[2].max+'%)</option></select>';
      m += '</td></tr></table>';      
      if(Seed.cityData.city[citynum].prestigeInfo.blessings) 
      {
        if(Seed.cityData.city[citynum].prestigeInfo.blessings.indexOf(11) != -1) 
        {
          m += '<tr><td></td><td align=left><INPUT class='+city+' id=AsEnabled'+city+' type=checkbox '+(TrainOptions.AsEnabled[city]?'CHECKED':'')+'> Auto train '+unsafeWindow.unitcost['unt13'][0]+' '+translate("Min")+'.: <INPUT class='+city+' id=AsTroops'+city+' type=text size=4 maxlength=6 value="'+TrainOptions.AsTroops[city]+'"><INPUT type=checkbox class='+city+' id="AsSelectMax'+city+'"> '+translate("Max")+'.: <INPUT class='+city+' id=Asmax'+city+' type=text size=5 maxlength=6 value="'+ TrainOptions.AsMax[city]+'"\></td>';
        };
        if(Seed.cityData.city[citynum].prestigeInfo.blessings.indexOf(21) != -1) 
        {
          m += '<tr><td></td><td align=left><INPUT class='+city+' id=AsEnabled'+city+' type=checkbox '+(TrainOptions.AsEnabled[city]?'CHECKED':'')+'> Auto train '+unsafeWindow.unitcost['unt14'][0]+' '+translate("Min")+'.: <INPUT class='+city+' id=AsTroops'+city+' type=text size=4 maxlength=6 value="'+TrainOptions.AsTroops[city]+'"><INPUT type=checkbox class='+city+' id="AsSelectMax'+city+'"> '+translate("Max")+'.: <INPUT class='+city+' id=Asmax'+city+' type=text size=5 maxlength=6 value="'+ TrainOptions.AsMax[city]+'"\></td>';
        };
        if(Seed.cityData.city[citynum].prestigeInfo.blessings.indexOf(31) != -1) 
        {
          m += '<tr><td></td><td align=left><INPUT class='+city+' id=AsEnabled'+city+' type=checkbox '+(TrainOptions.AsEnabled[city]?'CHECKED':'')+'> Auto train '+unsafeWindow.unitcost['unt15'][0]+' '+translate("Min")+'.: <INPUT class='+city+' id=AsTroops'+city+' type=text size=4 maxlength=6 value="'+TrainOptions.AsTroops[city]+'"><INPUT type=checkbox class='+city+' id="AsSelectMax'+city+'"> '+translate("Max")+'.: <INPUT class='+city+' id=Asmax'+city+' type=text size=5 maxlength=6 value="'+ TrainOptions.AsMax[city]+'"\></td>';
        };
      }; 
      m += '</td></tr></table>';
    }
      
    t.myDiv.innerHTML = m;
      
    jQuery("#pbTrainPresetCraftLimitPreset").append(
      jQuery('<option></option>').val(0).html("---")
    );

    for (i = 1 ; i <= Seed.throne.slotNum ; i++)
    {
      jQuery("#pbTrainPresetCraftLimitPreset").append(
        jQuery('<option></option>').val(i).html(i)
      );
    }

    jQuery("#pbTrainPresetCraftLimitPreset").val(Options.trainingThronePreset);

    jQuery("#pbTrainPresetCraftLimitPreset").change(function()
    {
      Options.trainingThronePreset = this.value; 
      saveOptions();
    });


    for (i=0;i<Seed.cities.length;i++)
    {
      city = i+1;
      document.getElementById('TroopsCity'+city).value = TrainOptions.Troops[city];
      document.getElementById('SelectCity'+city).checked = TrainOptions.Enabled[city];
      document.getElementById('Resource'+city).value = TrainOptions.Resource[city];
      document.getElementById('SelectMax'+city).checked = TrainOptions.SelectMax[city];
      document.getElementById('workers'+city).value = TrainOptions.Workers[city];
      document.getElementById('TrainSpeed_'+city).value = TrainOptions.Gamble[city];
      document.getElementById('TrainSpeedItem_'+city).value = TrainOptions.Item[city];
      
      if (!TrainOptions.SelectMax[city]) 
        document.getElementById('max'+city).disabled=true;
      
      if(document.getElementById('AsEnabled'+city)) 
      {
        document.getElementById('AsEnabled'+city).checked = TrainOptions.AsEnabled[city];
        document.getElementById('AsTroops'+city).value = TrainOptions.AsTroops[city];
        document.getElementById('AsSelectMax'+city).checked = TrainOptions.AsSelectMax[city];
        
        if (!TrainOptions.AsSelectMax[city]) 
        {
          document.getElementById('Asmax'+city).disabled=true;
        }
      }
    }
       
    document.getElementById('pbShowTrainHelp').addEventListener('click', function()
    {
      t.helpPop(this);
    }, false);
       
    document.getElementById('pbAutoTrainState').addEventListener('click', function()
    {
      t.toggleAutoTrainState(this);
    }, false);

    for(var k=1; k<=Seed.cities.length; k++)
    {
      document.getElementById('treshold'+k).addEventListener('change', function(e)
      {
        if (isNaN(e.target.value)) 
          e.target.value=0 ;
        
        TrainOptions.Threshold[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('SelectMax'+k).addEventListener('change', function(e)
      {
        TrainOptions.SelectMax[e.target['className']] = e.target.checked;
        if (!TrainOptions.SelectMax[e.target['className']])
        {
          document.getElementById('max'+e.target['className']).value = 0;
          document.getElementById('max'+e.target['className']).disabled=true;
        } 
        else 
        {
          document.getElementById('max'+e.target['className']).disabled=false;
        }
      
        saveTrainOptions();
      }, false);
      document.getElementById('max'+k).addEventListener('change', function(e)
      {
        TrainOptions.Max[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('workers'+k).addEventListener('change', function(e)
      {
        TrainOptions.Workers[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('Resource'+k).addEventListener('change', function(e)
      {
        TrainOptions.Resource[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('TrainSpeed_'+k).addEventListener('change', function(e)
      {
        TrainOptions.Gamble[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('TrainSpeedItem_'+k).addEventListener('change', function(e)
      {
        TrainOptions.Item[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('SelectCity'+k).addEventListener('change', function(e)
      {
        TrainOptions.Enabled[e.target['className']] = e.target.checked;
        saveTrainOptions();
      }, false);
      
      document.getElementById('TroopsCity'+k).addEventListener('change', function(e)
      {
        TrainOptions.Troops[e.target['className']] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('KeepFood'+k).addEventListener('change', function(e)
      {
        if (isNaN(e.target.value)) 
          e.target.value=0 ;
        
        TrainOptions.Keep[e.target['className']]['Food'] = e.target.value;
        saveTrainOptions();
      }, false);
        
      document.getElementById('KeepWood'+k).addEventListener('change', function(e)
      {
        if (isNaN(e.target.value)) 
          e.target.value=0 ;
        TrainOptions.Keep[e.target['className']]['Wood'] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('KeepStone'+k).addEventListener('change', function(e)
      {
        if (isNaN(e.target.value)) 
          e.target.value=0 ;
        
        TrainOptions.Keep[e.target['className']]['Stone'] = e.target.value;
        saveTrainOptions();
      }, false);
      
      document.getElementById('KeepOre'+k).addEventListener('change', function(e)
      {
        if (isNaN(e.target.value)) 
          e.target.value=0 ;
        TrainOptions.Keep[e.target['className']]['Ore'] = e.target.value;
        saveTrainOptions();
      }, false);
      
      if(document.getElementById('AsEnabled'+k)) 
      {  
        document.getElementById('AsEnabled'+k).addEventListener('change', function(e)
        {
          TrainOptions.AsEnabled[e.target['className']] = e.target.checked;
          saveTrainOptions();
        }, false);
        document.getElementById('AsTroops'+k).addEventListener('change', function(e)
        {
          if (isNaN(e.target.value)) 
            e.target.value=0 ;
          
          TrainOptions.AsTroops[e.target['className']] = e.target.value;
          saveTrainOptions();
        }, false);
        document.getElementById('Asmax'+k).addEventListener('change', function(e)
        {
          TrainOptions.AsMax[e.target['className']] = e.target.value;
          saveTrainOptions();
        }, false);
        document.getElementById('AsSelectMax'+k).addEventListener('change', function(e)
        {
          TrainOptions.AsSelectMax[e.target['className']] = e.target.checked;
          
          if (!TrainOptions.AsSelectMax[e.target['className']]){
            document.getElementById('Asmax'+e.target['className']).value = 0;
            document.getElementById('Asmax'+e.target['className']).disabled=true;
          } 
          else 
          {
            document.getElementById('Asmax'+e.target['className']).disabled=false;
          }
          saveTrainOptions();
        }, false);
      }
    } 
  },
  
  
  helpPop : function ()
  {
    var helpText = '<BR><DL><dt>Autotrain:<dd><LI>Toggle the box in front of the row to enable autotrain for that city (the number is the citynumer).</dd>\
                    <dd><LI>Select a trooptype per city in the dropdown boxes.</dd>\
                    <dd><LI>Fill in the minimum troops that triggers the autotrain (less then this will not be trained).</dd>\
                    <dt>Fill in resources:</dt>\
                    <dd><LI>Keep: Autotrain will keep this amount available in the city.</dd>\
                    <dd><LI>Use: Autotrain will only use the resources to train troops.</dd>\
                    <dt>Turn it on: </dt>\
                    <dd><LI>Hit the AutoTrain toggle button.</dd></ul>';
    var pop = new pbPopup ('giftHelp', 0, 0, 550, 230, true);
    pop.centerMe (mainPop.getMainDiv());  
    pop.getMainDiv().innerHTML = helpText;
    pop.getTopDiv().innerHTML = '<CENTER><B>Power Bot '+translate("Help")+'</b>:  '+translate("Auto Train")+'</center>';
    pop.show (true);
  },
  
  toggleAutoTrainState: function(obj)
  {
    var t = Tabs.AutoTrain;
    
    if (TrainOptions.Running == true) 
    {
      TrainOptions.Running = false;
      obj.value = translate("AutoTrain = OFF");
    }
    else 
    {
      TrainOptions.Running = true;
      obj.value = translate("AutoTrain = ON");
      t.nextcity();
    }
    
    saveTrainOptions();
  },
    
  show: function()
  {
    var t = Tabs.AutoTrain;
  },
  
  hide: function()
  {
    var t = Tabs.AutoTrain;
  },
  
  checkidlepopulation : function(cityId)
  {
    var t = Tabs.AutoTrain;
    if(TrainOptions.Workers[t.city] == 0)
      t.idle = parseInt(Seed.citystats['city'+cityId].pop[0]) - parseInt(Seed.citystats['city'+cityId].pop[3]);
    else
      t.idle = ((TrainOptions.Workers[t.city]/100)*parseInt(Seed.citystats['city'+cityId].pop[0])).toFixed(0);
  
    return t.idle > 0 ? true : false;
  },
  
  checktrainslots : function(cityId,prest)
  {
    var t = Tabs.AutoTrain;
    
    if(!prest) 
    {
      t.barracks = getCityBuilding(cityId, 13).count;
      t.slots = 0;
      
      for (k in Seed.queue_unt['city'+cityId])
        if(Seed.queue_unt['city'+cityId][k][7] == false)
          t.slots += 1;
    
      t.empty = parseInt(t.barracks - t.slots);
      return t.empty > 0 ? true : false;
    } 
    else 
    {
      t.barracks = Number(getCityBuilding(cityId, 22).count + getCityBuilding(cityId, 24).count + getCityBuilding(cityId, 26).count);//24 fey barracks, 22 druid barracks 26 briton barracks
      t.slots = 0;
      
      for (k in Seed.queue_unt['city'+cityId])
        if(Seed.queue_unt['city'+cityId][k][7] == true)
          t.slots += 1;
    
      t.empty = parseInt(t.barracks - t.slots);
      return t.empty > 0 ? true : false;
    }
  },
  
  checkresources : function(cityId)
  {
    var t = Tabs.AutoTrain;
    t.food = parseInt((Seed.resources['city'+cityId].rec1[0]/3600) - TrainOptions['Keep'][t.city]['Food']);
    t.wood = parseInt((Seed.resources['city'+cityId].rec2[0]/3600) - TrainOptions['Keep'][t.city]['Wood']);
    t.stone = parseInt((Seed.resources['city'+cityId].rec3[0]/3600) - TrainOptions['Keep'][t.city]['Stone']);
    t.ore = parseInt((Seed.resources['city'+cityId].rec4[0]/3600) - TrainOptions['Keep'][t.city]['Ore']);
    if(t.food>0 && t.wood>0 && t.stone>0 && t.ore>0)
    {
      return true;
    }
  
    return false;
  },
  
  trainamt : function(cityId, unitId)
  {
    var t = Tabs.AutoTrain;
    
    if(!unitId || unitId<1) 
      return false;
  
    var cost = unsafeWindow.Object.clone(unsafeWindow.unitcost['unt'+ unitId]);
    var gamble = (parseInt(TrainOptions.Gamble[t.city])>0)?t.gamble[TrainOptions.Gamble[t.city]].cost:1;
    t.amt = (t.idle/cost[6]).toFixed(0);
    
    for(var rs=1; rs<5; rs++)
      cost[rs] *= gamble;
    
    if ((t.food/cost[1]) < t.amt) 
      t.amt = (t.food/cost[1]).toFixed(0);
    
    if ((t.wood/cost[2]) < t.amt) 
      t.amt = (t.wood/cost[2]).toFixed(0);
    
    if ((t.stone/cost[3]) < t.amt) 
      t.amt = (t.stone/cost[3]).toFixed(0);
    
    if ((t.ore/cost[4]) < t.amt) 
      t.amt = (t.ore/cost[4]).toFixed(0);
    
    if (unitId < 13) 
    {
      if(TrainOptions.SelectMax[t.city])
      {
        if(parseInt(t.amt) > parseInt(TrainOptions.Max[t.city])) 
          t.amt = TrainOptions.Max[t.city];
      }
    
      if(parseInt(t.amt) < parseInt(TrainOptions.Threshold[t.city])) 
        t.amt = 0;
    }
    else
    {
      if(TrainOptions.AsSelectMax[t.city])
      {
        if(parseInt(t.amt) > parseInt(TrainOptions.AsMax[t.city])) 
        {
          t.amt = TrainOptions.AsMax[t.city];
        }
      }
    
      if(parseInt(t.amt) < parseInt(TrainOptions.AsTroops[t.city])) 
      {
        t.amt = 0;
      }
    }
    return t.amt > 0 ? true : false;
  },
  
  nextcity : function()
  {
    var t = Tabs.AutoTrain;
    
    if (!TrainOptions.Running) 
      return;
    
    t.city++;
  
    if(t.city > Seed.cities.length) 
      t.city = 1;
  
    if (Options.trainingThronePreset != 0) 
    {
      if (Seed.throne.activeSlot != Options.trainingThronePreset) 
      {
        setTimeout(t.nextcity, 2000);
        return;
      }
    }

    var cityId = Seed.cities[t.city-1][0];
    var idle = t.checkidlepopulation(cityId);
    var resources = t.checkresources(cityId);
    
    if(Seed.cityData.city[cityId].isPrestigeCity) 
    {
      var ptrainslots = t.checktrainslots(cityId,true);
      var punit = false;
      
      if(getCityBuilding(cityId, 22).count)
        punit = 13;
      if(getCityBuilding(cityId, 24).count)
        punit = 14;
      if(getCityBuilding(cityId, 26).count)
        punit = 15;
      if(punit) 
        var ptrain = t.trainamt(cityId, punit);
      
      if(TrainOptions.AsEnabled[t.city] && idle && ptrainslots && resources && ptrain) 
      {
        t.doTrain(cityId, punit, t.amt, t.nextcity, TrainOptions.Item[t.city]);
        t.city--;
        return;
      }
    }
    
    var trainslots = t.checktrainslots(cityId);
    var train = t.trainamt(cityId, TrainOptions['Troops'][t.city]);
    
    if(!TrainOptions.Enabled[t.city] || TrainOptions['Troops'][t.city]==0 || !idle || !trainslots || !resources || !train)
    {
      setTimeout(t.nextcity, 2000);
      return;
    }
    
    t.doTrain(cityId, TrainOptions['Troops'][t.city], t.amt, t.nextcity, TrainOptions.Item[t.city]);
  },
  
  doTrain : function (cityId, unitId, num, notify, tut)
  {
    var t = Tabs.AutoTrain;
    var time = unsafeWindow.modal_barracks_traintime(unitId, num);
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid = cityId;
    params.type = unitId;
    params.quant = num;
    
    if(parseIntNan(tut) > 0)
      params.items = tut;
    
    if(parseInt(TrainOptions.Gamble[t.city]) > 0)
      params.gambleId = TrainOptions.Gamble[t.city];

    if(params.type < 13)
      var inPrestige = false;
    else 
      var inPrestige = true;
      
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/train.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function(rslt) 
      {
        if (rslt.ok) 
        {
          for (var i = 1; i < 5; i++) 
          {
            var resourceLost = parseInt(unsafeWindow.unitcost["unt" + unitId][i]) * 3600 * parseInt(num);
            
            if(rslt.gamble) 
              resourceLost = resourceLost*rslt.gamble[i];
            
            unsafeWindow.seed.resources["city" + cityId]["rec" + i][0] = parseInt(unsafeWindow.seed.resources["city" + cityId]["rec" + i][0]) - resourceLost;
          }
          unsafeWindow.seed.citystats["city" + cityId].gold[0] = parseInt(unsafeWindow.seed.citystats["city" + cityId].gold[0]) - parseInt(unsafeWindow.unitcost["unt" + unitId][5]) * parseInt(num);
          unsafeWindow.seed.citystats["city" + cityId].pop[0] = parseInt(unsafeWindow.seed.citystats["city" + cityId].pop[0]) - parseInt(unsafeWindow.unitcost["unt" + unitId][6]) * parseInt(num);
          unsafeWindow.seed.queue_unt["city" + cityId].push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + time, 0, time, null, inPrestige]);
          setTimeout (notify, 2000);
          
          for (postcity in Seed.cities) 
            if (Seed.cities[postcity][0] == params.cid) 
              logcity = Seed.cities[postcity][1];
          
          if (Options.logAutoTrain) 
            actionLog(logcity  + ' Train ' + num + ':  ' + troops[unitId] );
        } 
        else 
        {
          setTimeout (notify, 2000);
        }
      },
    });
  },
}

/************************ Gold Collector ************************/
var CollectGold = {
  timer : null,
  lastCollect : {},
      
  init : function (){
    var t = CollectGold;
    for (var c=0; c<Cities.numCities; c++)
      t.lastCollect['c'+ Cities.cities[c].id] = 0;
    if (Options.pbGoldEnable)
      t.setEnable (true);
  },
  
  setEnable : function (tf){
    var t = CollectGold;
    clearTimeout (t.timer);
    if (tf)
      t.tick();
  },

  colCityName : null,
  colHappy : 0,  
  tick : function (){
    var t = CollectGold;
    for (var c=0; c<Cities.numCities; c++){
      var city = Cities.cities[c];
      var happy = Seed.citystats['city'+ city.id].pop[2];
      var since = unixTime() - t.lastCollect['c'+city.id];
      if (happy>=Options.pbGoldHappy && since>15*60){
        t.lastCollect['c'+city.id] = unixTime();
        t.colCityName = city.name;
        t.colHappy = happy;
        t.ajaxCollectGold (city, t.e_ajaxDone);
        break;
      }
    }
    t.timer = setTimeout (t.tick, 15000);    
  },

  e_ajaxDone : function (rslt){
    var t = CollectGold;
    if (rslt.ok)
      actionLog ('Collected '+ rslt.goldGained +' gold for '+ t.colCityName +' (happiness was '+ t.colHappy +')');
    else
      actionLog ('Error collecting gold for '+ t.colCityName +': <SPAN class=boldRed>'+ rslt.errorMsg +'</span>');
  },
  
  ajaxCollectGold : function (city, notify){
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid = city.id;
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/levyGold.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      onSuccess: function (rslt) {
        if (notify)  
          notify (rslt);
      },
      onFailure: function (rslt) {
        if (notify)  
          notify (rslt);
      }
    });
  },
}

/************************ Refresh Every X minutes ************************/
var RefreshEvery  = {
  timer : null,
  PaintTimer : null,
  NextRefresh : 0,
  box : null,
  target : null,
  
  init : function ()
  {
    var t = RefreshEvery;
    
    t.creatediv();
    
    if (Options.pbEveryMins < 1)
      Options.pbEveryMins = 1;
    
    RefreshEvery.setEnable (Options.pbEveryEnable);
  },
  
  creatediv : function()
  {
    var t = RefreshEvery;
    
    t.target = document.getElementById('comm_tabs');
    
    if(t.target == null)
    {
      setTimeout(t.creatediv, 2000);
      return;
    }
    
    t.box = document.createElement('div');
    t.target.appendChild(t.box);
  },
  
  delay : function (delaySeconds)
  {
    var t = RefreshEvery;

    t.NextRefresh += parseInt(delaySeconds);
  },
  
  setEnable : function (tf)
  {
    var t = RefreshEvery;
    clearTimeout (t.timer);

    if (tf) 
    {
      t.NextRefresh = unixTime() + (Options.pbEveryMins*60); 
      t.timer = setTimeout (t.Paint, 1000);
    } 
    else 
    {
      t.timer = null;
      t.NextRefresh = 0;
      t.box.innerHTML = '<BR><FONT color=white><B>&nbsp;&nbsp;&nbsp;&nbsp;'+ getMyAlliance()[1] + ' (' + getServerId() +')</b></font>';
    }
  },
  
  doit : function ()
  {
    actionLog ('Refreshing ('+ Options.pbEveryMins +' minutes expired)');
    reloadKOC();
  },
  
  setTimer : function ()
  {
    var t = RefreshEvery;
    
    clearTimeout (t.timer);
    
    if (Options.pbEveryMins < 1) 
    {
      Options.pbEveryMins = 1;
    }
    
    RefreshEvery.setEnable (Options.pbEveryEnable);
  },
  
  Paint : function()
  {
    var t = RefreshEvery;
    
    if(t.timer == null) 
    {
      return;
    }
    
    now = unixTime();

    var text = '';
    var Left = parseInt(t.NextRefresh - now);
    
    if ( Left < 0 )
    {
      Left = 0;
      t.doit();
    }
    
    if (Left < 60) 
    {
      text += '<div id=refreshTimeDisplay><BR>&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=white id=SuperTimer>'+translate("Next refresh in")+': </font><FONT color=red><B>'+ timestr(Left) +'</b></font></div>';
    }
    else 
    {
      text += '<div id=refreshTimeDisplay><BR>&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=white id=SuperTimer>'+translate("Next refresh in")+': <B>'+ timestr(Left) +'</b></font></div>';
    }
    
    jQuery('#refreshTimeDisplay').click(function()
    {
      RefreshEvery.delay(5 * 60);
    });
    
    t.box.innerHTML = text;
    t.timer = setTimeout (t.Paint, 1000);
  },
}

/************************ Fairie Killer ************************/
var FairieKiller  = {
  saveFunc : null,
  init : function (tf){
    if (firefoxVersion.substring(0,4) == '4.0b')  // bug in firefox 4.0b10 causes syntax error with: "var func = eval ('function (){}');"
      return;
    FairieKiller.saveFunc = unsafeWindow.Modal.showModalUEP;
    FairieKiller.setEnable (tf);
  },
  setEnable : function (tf){
    if (tf)
      unsafeWindow.Modal.showModalUEP = eval ('function FairieKiller (a,b,c) {actionLog ("Blocked Faire popup");}');
    else
      unsafeWindow.Modal.showModalUEP = FairieKiller.saveFunc;
  },
}

/********** facebook watchdog: runs only in 'http://apps.facebook.com/kingdomsofcamelot/*' instance!  ******/
function facebookWatchdog (){
  var INTERVAL = 50000; // wait 50 seconds minute before checking DOM
  if (!GlobalOptions.pbWatchdog)
    return;
  setTimeout (watchdog, INTERVAL);
  
// TODO: actionLog ?  
  function watchdog (){
    try {
//      if (document.getElementById('app_content_130402594779').firstChild.firstChild.childNodes[1].firstChild.tagName!='IFRAME'){
      if (document.getElementById('app_content_130402594779') == null){
        logit ("Watchdog: KOC NOT FOUND!");
        KOCnotFound(5*60);
      }
    } catch (e){
      logit ("Watchdog: KOC NOT FOUND! - exception");
      KOCnotFound(4*60);
    }
  }
}


function kocWatchdog ()
{
  var INTERVAL = 10000; // wait 30 seconds before checking DOM

  if (!GlobalOptions.pbWatchdog)
    return;

  setTimeout (watchdog, INTERVAL);
  
  function watchdog ()
  {
    logit ("KOC WATCHDOG: "+ document.getElementById('mod_maparea'));    
    
    if (document.getElementById('mod_maparea')==null)
    {
      logit ("Watchdog: KOC not loaded");
      KOCnotFound(20);
    }     
  }
}


function KOCnotFound(secs)
{
  var div;
  var countdownTimer = null;
  var endSecs = (new Date().getTime() / 1000) + secs;
    
  try 
  {  
    div = document.createElement('div');
    div.innerHTML = '<DIV style="font-size:18px; background-color:#a00; color:#fff"><CENTER><BR>'+translate("KOC Power Bot has detected that KOC is not loaded")+'<BR>'+translate("Refreshing in")+' <SPAN id=pbwdsecs></span><BR><INPUT id=pbwdcan type=submit value="'+translate("Cancel Refresh")+'"><BR><BR></div>';
    document.body.insertBefore (div, document.body.firstChild);
    document.getElementById('pbwdcan').addEventListener('click', cancel, false);
    countdown();
  } 
  catch (e) 
  {
    basicCountdown();
  }

  function countdown ()
  {
    var secsLeft = endSecs - (new Date().getTime() / 1000);

    jQuery('#pbwdsecs').html(timestr(secsLeft));
    logit("Watchdog: " + secsLeft + " seconds left");

    if (secsLeft < 0)
    {
      logit("Watchdog: we would reload here (1)");
      // reloadKOC();
    }

    countdownTimer = setTimeout (countdown, 1000);
  }

  function basicCountdown ()
  {
    var secsLeft = endSecs - (new Date().getTime()/1000);

    logit("Watchdog: " + secsLeft + " seconds left");

    if (secsLeft < 0)
    {
      logit("Watchdog: we would reload here (2)");
      // reloadKOC();
    }
    
    countdownTimer = setTimeout (countdown, 1000);
  }

  function cancel ()
  {
    clearTimeout (countdownTimer);
    document.body.removeChild (div);
  }
}

var WideScreen = 
{
  chatIsRight : false,
  useWideMap : false,
  rail : null,
  
  init : function ()
  {
    t = WideScreen;
    
    if (GlobalOptions.pbWideScreen)
    {
      t.rail = searchDOM (document.getElementById('mod_maparea'), 'node.className=="maparea_rrail"', 10);
      GM_addStyle ('.modalCurtain {width:760px !important} .mod_comm_mmb{z-index:0 !important}');  
      
      try 
      {
        document.getElementById('progressBar').parentNode.removeChild(document.getElementById('progressBar'));
        document.getElementById('crossPromoBarContainer').parentNode.removeChild(document.getElementById('crossPromoBarContainer'));
      } 
      catch (e) 
      {
      }
    }
  },
        
  setChatOnRight : function (tf){
    t = WideScreen;
    if (tf == t.chatIsRight || !GlobalOptions.pbWideScreen)
      return;
    if (tf){
      var chat = document.getElementById('kocmain_bottom').childNodes[1];
      if (!chat || chat.className!='mod_comm')
        setTimeout (function (){t.setChatOnRight(tf)}, 1000);
      chat.style.top = '-624px';
      chat.style.left = '760px';
      chat.style.height = '720px';
      chat.style.background = 'url("'+ CHAT_BG_IMAGE +'")';
      document.getElementById('mod_comm_list1').style.height = '580px';
      document.getElementById('mod_comm_list2').style.height = '580px';
    } else {
      var chat = document.getElementById('kocmain_bottom').childNodes[1];
      chat.style.top = '0px';
      chat.style.left = '0px';
      chat.style.height = '';
      chat.style.background = '';
      document.getElementById('mod_comm_list1').style.height = '287px';
      document.getElementById('mod_comm_list2').style.height = '287px';
    }
    t.chatIsRight = tf;
  },
  
  useWideMap : function (tf) {
    t = WideScreen;
    if (tf == t.useWideMap || !GlobalOptions.pbWideScreen)
      return;
    if (tf){
      t.rail.style.display = 'none';
      document.getElementById('mapwindow').style.height = "436px";
      document.getElementById('mapwindow').style.width = "1220px";
      document.getElementById('mapwindow').style.zIndex = "50";
    } else {
      t.rail.style.display = 'block';
      document.getElementById('mapwindow').style.height = "439px";
      document.getElementById('mapwindow').style.width = "760px";
      document.getElementById('mapwindow').style.zIndex = "";
    }
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Chat
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Chat = {
  tabOrder : 300,                    // order to place tab in top bar
  //tabDisabled : !ENABLE_SAMPLE_TAB, // if true, tab will not be added or initialized
  //tabLabel : 'Click Me',            // label to show in main window tabs
  myDiv : null,
  timer : null,  
  
  init : function (div){    // called once, upon script startup
    var t = Tabs.Chat;
    t.myDiv = div;
    unsafeWindow.pbviewtroops = t.viewtroops;
    t.myDiv.innerHTML = '<DIV class=pbStat>'+translate("Chat Answer/Reply Info")+'</div><TABLE><TR>\
            <TD><input type=checkbox id=pbchatqaenable /></td><TD>'+translate("Enable chat functions")+' </td></tr>\
            <TR><TD><input type=checkbox id=pbchatpassenable /></td><TD>'+translate("Enable password:")+'  <input type=text id=pbchatpass value="'+ ChatOptions.password +'"/></td>\
            <TD width=10px>&nbsp;</td><TD><input type=checkbox id=pbautoblacklist />'+translate("Auto blacklist players if 1st attempt fails")+'</td></tr>\
            <TR><TD></td><TD valign=top>'+translate("Allowed Players:")+' <br><textarea cols=30 rows=1 id=allowUserBox></textarea></td>\
            <TD width=10px>&nbsp;</td><TD> '+translate("Blacklisted Players")+' <br><textarea cols=30 rows=1 id=blacklistUserBox ></textarea></td></tr>\
            <TR><TD colspan=3>'+translate("Type \"/[Player] units?\" to get a unit count <br> Type \"/[Player] attacks? to get impending attacks")+' <br> '+translate("Player name is cAsE-SeNsItIvE")+' </td></tr></table>';
  t.togtext('allowUserBox', 'AllowUsersRemoteControl');
  t.togtext('blacklistUserBox', 'BlacklistUsersRemoteControl');
  t.togOpt('pbchatqaenable', 'Chatenable', ChatStuff.init);
  t.togOpt('pbchatpassenable', 'Chatpassenable');
  t.togOpt('pbautoblacklist', 'Chatautoblacklist');
  document.getElementById('pbchatpass').addEventListener('change', function(e){
    ChatOptions.password = e.target.value;
    GM_log(e.target.value);
    saveChatOptions();
  }, false);
  },
  
  togtext : function(boxId, optionName){
    var t = Tabs.Chat;
  var e = document.getElementById(boxId);
  var text = '';
  for(i=0; i<ChatOptions[optionName].length; i++)
    text += ChatOptions[optionName][i]+'\n';
  e.value = text;
  e.addEventListener('change', new eventToggle(boxId, optionName).handler, false);
  function eventToggle (boxId, optionName){
      this.handler = handler;
      var optName = optionName;
      function handler(event){
      ChatOptions[optionName] = [];
    var values = this.value.split('\n');
        for(var i=0; i<values.length; i++)
      ChatOptions[optionName][i] = values[i];
        saveChatOptions();
      }
    }
  },
  
  togOpt : function (checkboxId, optionName, callEnable, callIsAvailable){
    var t = Tabs.Chat;
    var checkbox = document.getElementById(checkboxId);
    
    if (callIsAvailable && callIsAvailable()==false){
      checkbox.disabled = true;
      return;
    }
    if (ChatOptions[optionName])
      checkbox.checked = true;
    checkbox.addEventListener ('change', new eventToggle(checkboxId, optionName, callEnable).handler, false);
    function eventToggle (checkboxId, optionName, callOnChange){
      this.handler = handler;
      var optName = optionName;
      var callback = callOnChange;
      function handler(event){
        ChatOptions[optionName] = this.checked;
        saveOptions();
        if (callback != null)
          callback (this.checked);
      }
    }
  },
  
  viewtroops : function (u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12){
  var t = Tabs.Chat;
    t.popReport = new pbPopup('pbShowTroops', 0, 0, 500, 300, true);
    t.popReport.centerMe (mainPop.getMainDiv());  
    var m = '<DIV style="max-height:275px; height:275px; overflow-y:scroll">'; 
    
    m+='<TABLE class=ptTab>\
    <TR><TD><b>'+translate("Impending Attack")+'</b></td></tr></table>';
  m+='<TABLE class=ptTab><TR><TD align="center">'+translate("Troops")+'</td><TD align="center">'+translate("Amount")+'</td></tr>';
  
  if(u1) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_1_30.png></td><TD align="center">'+parseInt(u1)+'</td></tr>';
  if(u2) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_2_30.png></td><TD align="center">'+parseInt(u2)+'</td></tr>';
  if(u3) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_3_30.png></td><TD align="center">'+parseInt(u3)+'</td></tr>';
  if(u4) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_4_30.png></td><TD align="center">'+parseInt(u4)+'</td></tr>';
  if(u5) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_5_30.png></td><TD align="center">'+parseInt(u5)+'</td></tr>';
  if(u6) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_6_30.png></td><TD align="center">'+parseInt(u6)+'</td></tr>';
  if(u7) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_7_30.png></td><TD align="center">'+parseInt(u7)+'</td></tr>';
  if(u8) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_8_30.png></td><TD align="center">'+parseInt(u8)+'</td></tr>';
  if(u9) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_9_30.png></td><TD align="center">'+parseInt(u9)+'</td></tr>';
  if(u10) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_10_30.png></td><TD align="center">'+parseInt(u10)+'</td></tr>';
  if(u11) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_11_30.png></td><TD align="center">'+parseInt(u11)+'</td></tr>';
  if(u12) m+='<TR><TD align="center"><img src=http://koc.god-like.info/img/unit_12_30.png></td><TD align="center">'+parseInt(u12)+'</td></tr>';
  
    m+='<TR><TD></TD></TR><TR><TD></TD></TR></table>';
  
  m+='</div>';
    t.popReport.getMainDiv().innerHTML = m;
    t.popReport.getTopDiv().innerHTML = '<TD><CENTER><B>'+translate("Incoming")+'</b></center></td>';
    t.popReport.show(true)  ;
  },
  
  hide : function (){

  },
  
  show : function (){

  },

}

var ChatStuff = {
timeout : null,
processqueue : [],
latestChats : [],

  init:function() {
  var t=ChatStuff;
  var comm=document.getElementById('mod_comm_list2');
  if(comm && ChatOptions.Chatenable) {
    if(t.timeout == null) {
      t.GetLatestChat();
      t.timeout = window.setTimeout(function() {
        t.IterateChat(t.ChatAdded);
      },200);
    } else {
      logit("Maybe too many chat messages, chat already processing.");
    }
  }
  window.setTimeout(function() {
    t.init();
  },5000);
  },

  GetLatestChatStr:function(chatObj) { 
  return chatObj.name+'#'+chatObj.time+'#'+chatObj.text.split(/[\.\?]/)[0]; 
  },

  GetLatestChat:function() {
  var t = ChatStuff;
  t.latestChats = ChatOptions.latestChats;
  if(t.latestChats.length>25) {
    t.latestChats.splice(0,1);
  }
  },

  GetChatTimeNum:function(time) {
  var tarr=time.split(':');
  if(!time) return undefined;
  var timeNum=(tarr[0]*60)+tarr[1];
  return timeNum;
  },

  GetChatObj:function(htmlObj) {
  var t=ChatStuff;
  var nm=searchDOM(htmlObj,'node.className=="nm"',8);
  var time=searchDOM(htmlObj,'node.className=="time"',8);
  var tx=searchDOM(htmlObj,'node.className=="tx"',8);
  if(!nm || !time || !tx) { return undefined; }
  var nameArr=nm.innerHTML.split(' ');
  var fromMe = nameArr[1]==Seed.player.name?true:false;
  return { 
    'obj':htmlObj,
    'textObj':tx,
    'name':nm.innerHTML,
    'time':time.innerHTML,
    'text':tx.innerHTML,
    'shortName':nameArr[1],
    'timeNum':t.GetChatTimeNum(time.innerHTML),
    'fromMe':fromMe?1:0,
  };
  },

  IterateChat:function(func) {
  var t=ChatStuff;
  var comm = document.getElementById('mod_comm_list2');
  var directs = searchDOM(comm,'node.className=="chatwrap clearfix direct"',4,true);
  var chats=[];
  for(var d=directs.length-1; d>=0; d--) {
    var direct=directs[d];
    var chatObj=t.GetChatObj(direct);
    if(chatObj) {
      chats.push([direct,chatObj]);
    }
  }
  t.checkProcessed(chats, func);
  },

  checkProcessed : function(chats, func){
  var t=ChatStuff;
  for(var c=0; c<chats.length; c++) {
    var found = false;
    var chatObj=chats[c][1];
    for(var i=0; i<t.latestChats.length; i++){
      if(t.latestChats[i] == t.GetLatestChatStr(chatObj))
        found = true;
    }
    if(!found){
    chatObj.notProcessed=true;
    ChatOptions.latestChats.push(t.GetLatestChatStr(chatObj));
    }
    func(chatObj);
  }
  saveChatOptions();
  t.timeout = null;
  },

  GetCitiesHash:function(arr) {
  var h={};
  for(var a=0; a<arr.length; a++) {
    var city=arr[a];
    var newA=[]
    Array.prototype.push.apply(newA, city);

    h[city[0]]=newA;
  }
  return h;
  },

  SendChat:function(name,mess) {
  var inp=document.getElementById('mod_comm_input');
  inp.value="@"+name+' '+mess;
  logit('Send chat:'+mess);
  unsafeWindow.Chat.sendChat();
  },

  ChatFuncs:{
  'units':{
    'question':function(chatObj,info) {
      if(!chatObj.notProcessed) { return; }
      var t=ChatStuff;
      
      t.SendChat(chatObj.shortName,"units."+JSON2.stringify({
        'cities':t.GetCitiesHash(Seed.cities),
        'units':Seed.units,
      }));
    },
    'answer':function(chatObj,info) {
      var t=ChatStuff;
      // {"city24479":{"tick":1297589617,"rec1":"[756220044, 2592000000, 7100, 3033]","rec2":"[539696566, 1836000000, 5000, 0]","rec3":"[191319892, 1548000000, 4200, 0]","rec4":"[4512787, 1512000000, 4100, 0]"}}
      var infoObj=JSON2.parse(info);
      var res=infoObj.units;
      var cities=infoObj.cities;
      
      chatObj.textObj.innerHTML='';
      var table=document.createElement('table');
      //table.className='direct';
      function AddCell(tr) {
        var td=tr.insertCell(-1);
        //td.className='direct';
        td.style.backgroundColor='#ffde75';
        td.style.textAlign='right';
        return td;
      }
      for(var city in res) {
        var resObj=res[city];
        
        var tr=table.insertRow(-1);
        //var cityTd=tr.insertCell(-1);
        var cityTd=AddCell(tr);
        cityTd.colspan='4';
        cityTd.style.fontWeight='bold';
        var cityM=/([0-9]+)$/.exec(city);
        var cityObj=cities[cityM[1]];
        if(!cityObj) {
          logit('Cannot find city:'+cityM[1]);
          continue; 
        }
        
        cityTd.innerHTML=cityObj[1];
        //for(var r=1; r<=4; r++ ) {
        for(var unt in resObj) {
          //var rarr=JSON2.parse(resObj['rec'+r].replace(' ',''));
          var units=parseInt(resObj[unt]);
          
          if(units<=0) continue;
          var tr=table.insertRow(-1);
          AddCell(tr).innerHTML=unsafeWindow.unitcost[unt][0];
          AddCell(tr).innerHTML=addCommas(units);
        }
      }
      chatObj.textObj.appendChild(table);
    },
  },
  'attacks':{
    'question':function(chatObj,info) {
      if(!chatObj.notProcessed) { return; }
      var t=ChatStuff;
      
      t.SendChat(chatObj.shortName,"attacks."+JSON2.stringify({
        'cities':t.GetCitiesHash(Seed.cities),
        'marches':Seed.queue_atkinc,
        'players':Seed.players,
        'alliance':Seed.allianceNames,
      }));
    },
    'answer':function(chatObj,info) {
      var t=ChatStuff;
      var infoObj=JSON2.parse(info);
      var res=infoObj.marches;
      var cities=infoObj.cities;
      var names=infoObj.players;
      var alliance=infoObj.alliance;
      
      chatObj.textObj.innerHTML='';
      var div = document.createElement('div');
      var table=document.createElement('table');
      div.style.overflow = 'auto';
      function AddCell(tr) {
        var td=tr.insertCell(-1);
        td.style.backgroundColor='#ffde75';
        td.style.textAlign='right';
        return td;
      }
      var cityTr = {};
      for(var city in cities) {       
        cityTr[city]=table.insertRow(-1);
        cityTd=AddCell(cityTr[city]);
        cityTd.colspan='4';
        cityTd.style.fontWeight='bold';
        cityTd.innerHTML=cities[city][1].substring(0,10)+' '+coordLink(cities[city][2],cities[city][3]);
      }
      for(var marches in res){
        var marchObj = res[marches];
        if(!marchObj.toCityId) continue;
        if(marchObj.marchType == 3 || marchObj.marchType ==4){
          var tr=table.insertRow(cityTr[marchObj.toCityId].rowIndex+1);//Specify which city to insert
          var timeLeft = parseInt(marchObj.arrivalTime-unixTime());
          if(timeLeft < 0) continue;
          
          AddCell(tr).innerHTML = timestr(timeLeft);
          AddCell(tr).innerHTML = coordLink(marchObj.fromXCoord,marchObj.fromYCoord);
          AddCell(tr).innerHTML = names['u'+marchObj.pid]?names['u'+marchObj.pid].n.substring(0,10):(marchObj.players['u'+marchObj.pid]?marchObj.players['u'+marchObj.pid].n.substring(0,10):'Undefined');
          AddCell(tr).innerHTML = (alliance['a'+marchObj.fromAllianceId]?alliance['a'+marchObj.fromAllianceId].substring(0,10):'Undefined')+' ('+getDiplomacy(marchObj.fromAllianceId)+')';
          var troops = [];
          for(var t = 1; t<13; t++){
            troops.push(parseInt(marchObj.unts['u'+t]));
          }
          AddCell(tr).innerHTML = '<a onclick=pbviewtroops('+ troops.join(',') +')>'+translate("View troops")+'</a>';
        }
      }
      div.appendChild(table);
      chatObj.textObj.appendChild(div);
    },
  }
  },

  allowUsersHash:null,
  ChatAdded:function(chatObj) {
  var t=ChatStuff;
  if(chatObj) {
    t.noAllow = ChatOptions.BlacklistUsersRemoteControl;
    t.allowUsersHash = ChatOptions.AllowUsersRemoteControl;
    if(t.allowUsersHash.length==0) { return; }
    if(t.noAllow.length!=0) {
      for(var u=0; u<t.noAllow.length; u++)
        if(t.noAllow[u] == chatObj.shortName){
          return;
        }
    }

    var cArr=/^([^\?\.]+)([\.\?])(.*)$/.exec(chatObj.text);
    if(!cArr) {
      return;
    }
    var cmd=cArr[1];
    
    var question=false;
    if(chatObj.fromMe) {
      chatObj.obj.style.borderBottom='1px solid #0f0';
    }
    if(chatObj.notProcessed) {
      chatObj.obj.style.borderLeft='1px solid #ff0';
    }
    
    var cmdInfo=t.ChatFuncs[cmd];

    if(cArr[2]=='?') {
      question=true;
      if(ChatOptions.Chatpassenable){
        var password=cArr[3];
      }
    } else {
      var info=cArr[3];
    }
    
    if(cmdInfo && !question) {
      // hide unreadable requests that are json
      var shortCmd=(cmd+cArr[2]);

      if(chatObj.textObj.innerHTML!=shortCmd && info.substr(0,1)=='{') {
        chatObj.textObj.innerHTML=shortCmd;
      }
    }
    
    // if(chatObj.fromMe) {
      // return;
    // }
    var done=0;

    if(cmdInfo) {
      window.setTimeout(function() {
        if(question && chatObj.notProcessed) {
          var permission = false;
          for(var u=0; u<t.allowUsersHash.length; u++)
            if(t.allowUsersHash[u] == chatObj.shortName){
              permission = true;
              break;
            }
          if(ChatOptions.Chatpassenable && password!=ChatOptions.password){
            permission = false;
            //GM_log(password+' '+ChatOptions.password);
          }
          if(permission){
            cmdInfo['question'].call(t,chatObj,info);
          } else {
            chatObj.obj.appendChild(document.createTextNode(translate("Player does not have permission")+": "+chatObj.shortName));
            t.SendChat(chatObj.shortName,translate("Player does not have permission"));
            if(ChatOptions.Chatautoblacklist){
              ChatOptions.BlacklistUsersRemoteControl.push(chatObj.shortName);
              document.getElementById('blacklistUserBox').value += chatObj.shortName+'\n';
            }
          }
        } else {
          cmdInfo['answer'].call(t,chatObj,info);
        }
      },0);       
    }
  } else {
    logit('Chat object failed');
  }
  return true;
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Language
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Language = {
  tabOrder : 800,                    // order to place tab in top bar
  tabLabel : 'Language',            // label to show in main window tabs
  myDiv : null,
  language : {needTranslation:{}},
  link : {"http://koc-power-bot.googlecode.com/svn/trunk/translation/translation_en.js":"en"},
  
  init : function (div){    // called once, upon script startup
    var t = Tabs.Language;
    t.myDiv = div;
    var m = "<DIV class=pbStat>"+translate("Language Settings")+"</div><TABLE><TR>\
      <TD>"+translate("Set Language")+" : "+ htmlSelector({en:"en"},Options.language,"id=pblang_type") +"</td>\
      <TD><input id=pblang_update value='"+translate("Save Settings")+"' type=submit DISABLED /><span id=pblang_msg ></span></td></tr>\
      <TR><TD>"+translate("Language files download")+" : "+ htmlSelector(t.link,null,"id=pblang_link") +"</td>\
      <td><input id=pblang_download value='"+translate("Download")+"' type=submit /></td></tr>\
      <TR><TD>"+translate("Show current language array:")+" </td>\
      <TD><input id=pblang_show value='"+translate("Show")+"' type=submit /></td></tr>";
    t.myDiv.innerHTML = m;
    
    document.getElementById("pblang_type").addEventListener('change', function (){
    if(Options.language != document.getElementById("pblang_type").value)
      document.getElementById("pblang_update").disabled = false;
    else
      document.getElementById("pblang_update").disabled = true;
  },false);
  document.getElementById("pblang_update").addEventListener('click', function (){
    var language = document.getElementById("pblang_type").value;
    var s = GM_getValue ("Language_"+language);
    if (s != null){
      var lang = JSON2.parse (s);
      t.sendMessage("Loaded <b>"+language+"</b> Version <b>"+lang.Version+"</b>");
      Options.language = document.getElementById("pblang_type").value;
    } else {
      t.sendMessage("<span class=boldRed> Language <b>"+language+"</b> not found. Please download language file!</span>");
      document.getElementById("pblang_type").value = Options.language;
    }
  },false);
  document.getElementById("pblang_download").addEventListener('click', function (){
    document.getElementById("pblang_download").disabled = true;
    GM_xmlhttpRequest({
            method: 'GET',
      url: document.getElementById("pblang_link").value,
      onload: function(xpr) {t.updatelanguage(xpr.responseText, document.getElementById("pblang_link").value);},
            onerror: function(xpr) {t.updatelanguage(xpr.responseText, false);}
        });
  },false);
  document.getElementById("pblang_show").addEventListener('click', function(){
    t.showlanguage();
  },false);
  },
  
  hide : function (){         // called whenever the main window is hidden, or another tab is selected
    var t = Tabs.Language;
  },
  
  show : function (){
    
  },
  
  showlanguage : function(){
    var t = Tabs.Language;
    t.poplangshow = new pbPopup('pbShowLanguage', 10, 10, 600, 500, true, function() {t.poplangshow.destroy();});
    t.poplangshow.getTopDiv().innerHTML = '<TD><B>'+translate("Language Array:")+'</td>';
    t.poplangshow.getMainDiv().innerHTML = '<DIV style="max-height:440px;overflow-y:auto"><TABLE style="overflow-y:auto" align=center cellpadding=0 cellspacing=0 width=100% class="pbTab" id="pblang_showarray"></table></div><div id=pblang_status ></div>';
    t.paintlanguagearray();
    t.poplangshow.show(true);
  },
  
  paintlanguagearray : function(){
    var t = Tabs.Language;
    var m = '';
    for (var k in t.language.needTranslation){
      m += "<TR><TD style='max-width:250px;word-wrap:break-word' >"+k.escape_space()+": </td><TD><input id='pblang_"+escape(k)+"' value='"+(t.language.needTranslation[k]==1?'':t.language.needTranslation[k].unescape_space())+"' /></td></tr>";
    }
    for (var k in t.language){
      if(k != "needTranslation")
      m += "<TR><TD style='max-width:250px;word-wrap:break-word' >"+k.escape_space()+": </td><TD>"+t.language[k].escape_space()+"</td></tr>";
    }
    document.getElementById("pblang_showarray").innerHTML = m;
    document.getElementById("pblang_status").innerHTML = "<center><input type=submit id=pblang_statussave value=Save /><input type=submit id=pblang_statusexport value='Export new translation' /></center>";
    document.getElementById("pblang_statussave").addEventListener('click', function(){
    for (var k in t.language.needTranslation){
      var j = document.getElementById("pblang_"+escape(k)).value;
      if(j != '')
        t.language.needTranslation[k] = j;
    }
    saveLanguage();
    },false);
    document.getElementById("pblang_statusexport").addEventListener('click', function(){
      t.export();
    },false);
  },  
  
  export : function(){
    var t = Tabs.Language;
    var pop = new pbPopup('pbExportLanguage', 0, 0, 400, 400, true, function() {this.destroy();});
    var m = "<textarea rows=15 cols=50 >";
     for (var k in t.language.needTranslation){
      if(t.language.needTranslation[k] != 1)
        m += "\""+k+"\":\""+t.language.needTranslation[k]+"\",\n";
    }
    m += "</textarea>";
    pop.getMainDiv().innerHTML = m;
    pop.show(true);
  },
  
  sendMessage : function (msg){
    document.getElementById("pblang_msg").innerHTML = msg;
  },
  
  updatelanguage : function(result, response){
    var t = Tabs.Language;
    if(!response) {
      t.sendMessage("<span class=boldRed>Error loading file. Try again later</span>");
    document.getElementById("pblang_download").disabled = false;
      return;
    }
    var rslt = null;
    try{
    rslt = JSON2.parse(result);
    } catch (e){
    t.sendMessage("<span class=boldRed>Error reading file. Please notify devs</span>");
    logit(inspect(e,7,1));
    document.getElementById("pblang_download").disabled = false;
    return;
    }
    var s = GM_getValue ("Language_"+rslt.curlang);
    if (s != null){
    var lang = JSON2.parse (s);
    for (k in rslt){
      if(lang.needTranslation)
        if(lang.needTranslation[k]) //Remove from array if already translated
          delete lang.needTranslation[k];
      lang[k] = rslt[k];
    }
    } else {
      var lang = rslt;
    }
    setTimeout (function (){GM_setValue ('Language_'+rslt.curlang, JSON2.stringify(lang));}, 0);
    t.sendMessage("Successfully loaded language file. Please refresh");
    document.getElementById("pblang_download").disabled = false;
  },
}

function readLanguage () {
  var t = Tabs.Language;
  if(!Options.language) return;
  var s = GM_getValue ("Language_"+Options.language);
  if (s != null){
    var lang = JSON2.parse (s);
    for (k in lang){
      t.language[k] = lang[k];
    }
  }
  t.language.curlang = Options.language;
}

function saveLanguage (){
  var t = Tabs.Language;
  setTimeout (function (){GM_setValue ('Language_'+t.language.curlang, JSON2.stringify(t.language));}, 0);
}

function translate (str) {
  var t = Tabs.Language;
  if(t.language[str])
    return t.language[str];
  else {
    if(t.language.needTranslation[str] == undefined)
      t.language.needTranslation[str] = 1;
    else if (t.language.needTranslation[str] != 1)
      return t.language.needTranslation[str];
  }
  return str; 
}


/*******************   KOC Map interface ****************/
// 0:bog, 10:grassland, 11:lake, 20:woods, 30:hills, 40:mountain, 50:plain, 51:city / barb, 53:misted city
function CMapAjax (){
  this.normalize = normalize;  
  this.request = request;

  function request (left, top, width, notify){    
    var left = parseInt(left / 5) * 5;
    var top = parseInt(top / 5) * 5;
    var width = parseInt((width+4) / 5) * 5;
    
    var blockString = generateBlockList(left, top, width);
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.blocks = blockString;
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/fetchMapTiles.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) {
        notify(left, top, width, rslt);
      },
      onFailure: function (rslt) {
        notify(left, top, width, rslt);
      }
    });
    function generateBlockList (left, top, width) {
      var width5 = parseInt(width / 5);
      var bl = [];
      for (x=0; x<width5; x++){
        var xx = left + (x*5);
        if (xx > 745)
          xx -= 750;
        for (y=0; y<width5; y++){
          var yy = top + (y*5);
          if (yy > 745)
            yy -= 750;
          bl.push ('bl_'+ xx +'_bt_'+ yy);
        }
      }
      return bl.join(",");
    }
  }
 
  function normalize  (x){
    if ( x >= 750)
      x -= 750;
    else if (x < 0)
      x += 750;
    return parseInt (x/5) * 5;
  }
}

var anticd = {
  isInited : false,
  KOCversion : '?',
  
  init: function (){
    if (this.isInited)
      return this.KOCversion;
    CM.cheatDetector.detect = eval ('function a (){}');
    var scripts = document.getElementsByTagName('script');
    for (var i=0; i<scripts.length; i++){
      if (scripts[i].src.indexOf('camelotmain') >=0){
        break;
      }
    }
    if (i<scripts.length){
      var m = scripts[i].src.match (/camelotmain-(.*).js/);  
      if (m)
        this.KOCversion = m[1];
    }
    this.isInited = true;
    // more coming soon :)
  },
  
  getKOCversion : function (){
    return this.KOCversion;
  },
}
try {
  anticd.init ();
} catch (e){
  logit ("ANTICD error: "+ e);
}

var tabManager = {
  tabList : {},           // {name, obj, div}
  currentTab : null,
  
  init : function (mainDiv){
    var t = tabManager;
    var sorter = [];

    for (k in Tabs){
      if (!Tabs[k].tabDisabled){  
        t.tabList[k] = {};
        t.tabList[k].name = k;
        t.tabList[k].obj = Tabs[k];

        if (Tabs[k].tabLabel != null) {
          t.tabList[k].label = Tabs[k].tabLabel;
        } else {
          t.tabList[k].label = k;
        }

        if (Tabs[k].tabOrder != null) {
          sorter.push([Tabs[k].tabOrder, t.tabList[k]]);
        } else {
          sorter.push([1000, t.tabList[k]]);
        }
        
        t.tabList[k].div = document.createElement('div');
      }
    }

    sorter.sort (function (a,b) { return a[0] - b[0] } );
    
    var m = '<TABLE cellspacing=3 class=pbMainTab><TR>';

    for (var i=0; i<sorter.length; i++) {
      m += '<TD class=spacer></td><TD align=center class=notSel id=pbtc'+ sorter[i][1].name +' ><A><SPAN>'+ sorter[i][1].label +'</span></a></td>';
      if ((i+1)%9 == 0) {
        m+='</tr><TR>';
      }
    }
    
    m+='</tr></table>';  
    //m += '<TD class=spacer width=90% align=right>'+ Version +'&nbsp;</td></tr></table>';
    mainPop.getMainTopDiv().innerHTML = m;
    
    for (k in t.tabList) {
      if (t.tabList[k].name == Options.currentTab)
        t.currentTab =t.tabList[k] ;
      document.getElementById('pbtc'+ k).addEventListener('click', this.e_clickedTab, false);
      var div = t.tabList[k].div;
      div.style.display = 'none';
      div.style.height = '100%';
      mainDiv.appendChild(div);
      // try {
        t.tabList[k].obj.init(div);
      // } catch (e){
        // div.innerHTML = "INIT ERROR 1 : "+ e;
      // }
    }
    
    if (t.currentTab == null)
      t.currentTab = sorter[0][1];    
    t.setTabStyle (document.getElementById ('pbtc'+ t.currentTab.name), true);
    t.currentTab.div.style.display = 'block';
  },
  
  hideTab : function (){
    var t = tabManager;
    t.currentTab.obj.hide();
  },
  
  showTab : function (){
    var t = tabManager;
    t.currentTab.obj.show();
  },
    
  setTabStyle : function (e, selected){
    if (selected){
      e.className = 'sel';
    } else {
      e.className = 'notSel';
    }
  },
  
  e_clickedTab : function (e){
    var t = tabManager;
    var newTab = t.tabList[e.target.parentNode.parentNode.id.substring(4)];
    if (t.currentTab.name != newTab.name){
      t.setTabStyle (document.getElementById ('pbtc'+ t.currentTab.name), false);
      t.setTabStyle (document.getElementById ('pbtc'+ newTab.name), true);
      t.currentTab.obj.hide ();
      t.currentTab.div.style.display = 'none';
      t.currentTab = newTab;
      newTab.div.style.display = 'block';
      Options.currentTab = newTab.name;      
    }
    newTab.obj.show();
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function onUnload ()
{
  Options.pbWinPos = mainPop.getLocation();
  if (!ResetAll) saveOptions();
  saveLanguage();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function mouseMainTab (me)
{   // right-click on main button resets window location
  if (me.button == 2)
  {
    var c = getClientCoords (document.getElementById('main_engagement_tabs'));
    mainPop.setLocation ({x: c.x+4, y: c.y+c.height});
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function eventHideShow ()
{
  if (mainPop.toggleHide(mainPop)){
    tabManager.showTab();
    Options.pbWinIsOpen = true;
  } 
  else 
  {
    tabManager.hideTab();
    Options.pbWinIsOpen = false;
  }
  
  saveOptions();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function hideMe ()
{
  mainPop.show (false);
  tabManager.hideTab();
  Options.pbWinIsOpen = false;
  saveOptions();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function showMe ()
{
  mainPop.show (true);
  tabManager.showTab();
  Options.pbWinIsOpen = true;
  saveOptions();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function addMyFunction (func)
{      // add function to run in our own scope
  unsafeWindow[func.name] = func;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function addUwFunction (func)
{      // add function to run in unsafeWindow's scope
  var scr = document.createElement('script');
  scr.innerHTML = func.toString();
  document.body.appendChild(scr);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function alterUwFunction (funcName, frArray)
{
  try 
  {
    funcText = unsafeWindow[funcName].toString();
    rt = funcText.replace ('function '+funcName, 'function');
    for (i=0; i<frArray.length; i++){
      x = rt.replace(frArray[i][0], frArray[i][1]);
      if (x == rt)
        return false;
      rt = x;
    }
    js = funcName +' = '+ rt;
    var scr=document.createElement('script');
    scr.innerHTML=js;
    document.body.appendChild(scr);
    return true;
  } 
  catch (err) 
  {
    return false;
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function officerId2String (oid)
{
  if (oid==null)
    return '';
  else if (oid==3)
    return 'Officer';
  else if (oid==2)
    return 'Vice Chance';
  else if (oid==1)
    return 'Chancellor';
  return '';
}

var knightRoles = {
  Foreman : 'politics',
  Marshall : 'combat',
  Alchemystic : 'intelligence',
  Steward : 'resourcefulness',
};

function officerId2String (oid){
  if (oid==null)
    return '';
  else if (oid==3)
    return 'Officer';
  else if (oid==2)
    return 'Vice Chance';
  else if (oid==1)
    return 'Chancellor';
  return '';
}

var fortNamesShort = {
  53: "Crossbows",
  55: "Trebuchet",
  60: "Trap",
  61: "Caltrops",
  62: "Spiked Barrier",
}

// onClick (city{name, id, x, y}, x, y)   city may be null!
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function CdispCityPicker (id, span, dispName, notify, selbut, disable_list)
{
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  function CcityButHandler (t)
  {
    var that = t;
    this.clickedCityBut = clickedCityBut;
    function clickedCityBut (e)
    {
      if (that.selected != null)
        that.selected.className = "castleBut castleButNon";
      that.city = Cities.cities[e.target.id.substr(that.prefixLen)];
      
      if (that.dispName)
        document.getElementById(that.id+'cname').innerHTML = that.city.name;
      e.target.className = "castleBut castleButSel";
      that.selected = e.target;
      
      if (that.coordBoxX)
      {
        that.coordBoxX.value = that.city.x;
        that.coordBoxY.value = that.city.y;
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent('change', true, true ); // event type,bubbling,cancelable
        that.coordBoxX.dispatchEvent(evt);
        that.coordBoxY.dispatchEvent(evt);
        that.coordBoxX.style.backgroundColor = '#ffffff';
        that.coordBoxY.style.backgroundColor = '#ffffff';
      }
      
      if (that.notify != null)
        that.notify(that.city, that.city.x, that.city.y);
    }
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  function selectBut (idx)
  {
    document.getElementById(this.id+'_'+idx).click();
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  function bindToXYboxes (eX, eY)
  {
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Function Name :
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    function CboxHandler (t)
    {
      var that = t;
      this.eventChange = eventChange;
      
      if (that.city)
      {
        eX.value = that.city.x;
        eY.value = that.city.y;
      }
      
      /////////////////////////////////////////////////////////////////////////////////////////////////////////
      // Function Name :
      /////////////////////////////////////////////////////////////////////////////////////////////////////////
      function eventChange ()
      {
        var xValue=that.coordBoxX.value.trim();
        var xI=/^\s*([0-9]+)[\s|,|-|.]+([0-9]+)/.exec(xValue);        
      
        if(xI) 
        {
          that.coordBoxX.value=xI[1]
          that.coordBoxY.value=xI[2]
        }

        var x = parseInt(that.coordBoxX.value, 10);
        var y = parseInt(that.coordBoxY.value, 10);
        
        if (isNaN(x) || x<0 || x>750)
        {
          that.coordBoxX.style.backgroundColor = '#ff8888';
          return;
        }
        
        if (isNaN(y) || y<0 || y>750)
        {
          that.coordBoxY.style.backgroundColor = '#ff8888';
          return;
        }
        
        that.coordBoxX.style.backgroundColor = '#ffffff';
        that.coordBoxY.style.backgroundColor = '#ffffff';
        
        if (that.notify != null)
          that.notify (null, x, y);
      }
      return false;
    }
    
    this.coordBoxX = eX;
    this.coordBoxY = eY;
    var bh = new CboxHandler(this);
    eX.maxLength=8;
    eY.maxLength=3;
    eX.style.width='2em';    
    eY.style.width='2em';    
    eX.addEventListener('change', bh.eventChange, false);
    eY.addEventListener('change', bh.eventChange, false);
  }

  this.selectBut = selectBut;
  this.bindToXYboxes = bindToXYboxes;
  this.coordBoxX = null;
  this.coordBoxY = null;
  this.id = id;
  this.dispName = dispName;
  this.prefixLen = id.length+1;
  this.notify = notify;
  this.selected = null;
  this.city = null;
  var m = '';
  
  for (var i=0; i<Cities.cities.length; i++)
  {
    if(matTypeof(disable_list) == 'array')
    {
      if(disable_list[i])
        m += '<INPUT class="castleBut castleButNon" id="'+ id +'_'+ i +'" value="'+ (i+1) +'" type=submit DISABLED \>';
      else
        m += '<INPUT class="castleBut castleButNon" id="'+ id +'_'+ i +'" value="'+ (i+1) +'" type=submit \>';
    } 
    else
      m += '<INPUT class="castleBut castleButNon" id="'+ id +'_'+ i +'" value="'+ (i+1) +'" type=submit \>';
  }
  
  if (dispName)
    m += ' &nbsp; <SPAN style="display:inline-block; width:85px; font-weight:bold;" id='+ id +'cname' +'></span>';
  
  span.innerHTML = m;
  var handler = new CcityButHandler(this);
  
  for (var i=0; i<Cities.cities.length; i++)
    document.getElementById (id+'_'+i).addEventListener('click', handler.clickedCityBut, false);
  
  if (selbut != null)
    this.selectBut(selbut);
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function setCities()
{
  Cities.numCities = Seed.cities.length;
  Cities.cities = [];
  Cities.byID = {};
  
  for (i=0; i<Cities.numCities; i++)
  {
    city = {};
    city.idx = i;
    city.id = parseInt(Seed.cities[i][0]);
    city.name = Seed.cities[i][1];
    city.x = parseInt(Seed.cities[i][2]);
    city.y = parseInt(Seed.cities[i][3]);
    city.tileId = parseInt(Seed.cities[i][5]);
    city.provId = parseInt(Seed.cities[i][4]);
    getTroopDefTrainEstimates('city'+ city.id, city);
    Cities.cities[i] = city;
    Cities.byID[Seed.cities[i][0]] = city;
  }
}

var InitCode = 212121;
var DebugCode = 434343;
var TestCode = 676767;

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function checkVersion() 
{
  if(Options.Version != Version) 
  {
    logVersionUpdate();
    Options.Version = Version;
    saveOptions();
  }

  if(Seed.allianceDiplomacies != undefined && Seed.allianceDiplomacies.allianceId != undefined) 
  {
    EnableOptions = enableCheck(Seed.allianceDiplomacies.allianceId);
    if(Options.FullEnable)
      EnableOptions = true;
  } 
  else 
  {
    EnableOptions = false;
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getTroopDefTrainEstimates (cityID, city)
{
  var b = Seed.buildings[cityID];
  city.numCottages = 0;
  city.numBarracks = 0;
  city.maxBarracks = 0;
  city.totLevelsBarracks = 0;
  city.blacksmithLevel = 0;
  city.stableLevel = 0;
  city.workshopLevel = 0;
  city.wallLevel = 0;
  city.feyLevel = 0;
  
  for (var j=1; j<33; j++)
  {
    if (b['pos'+j]) 
    {
      var bname = parseInt(b['pos'+j][0]);
      var blvl = parseInt(b['pos'+j][1]);
      
      switch(bname)
      {
        case 13:
          city.numBarracks++;
          city.totLevelsBarracks += parseInt(blvl);
          if (blvl>city.maxBarracks) city.maxBarracks=blvl;
          break;
        case 5:
          city.numCottages++;
          break;
        case 15:
          city.blacksmithLevel = blvl;
          break;
        case 16:
          city.workshopLevel = blvl;
          break;
        case 17:
          city.stableLevel = blvl;
          break;
        case 19:
          city.wallLevel = blvl;
          break;
        case 20:
            city.feyLevel = blvl;
          break;
      }
    }
  }

  var now = unixTime();
  city.marshallCombatScore = 0;
  var s = Seed.knights[cityID];
  
  if (s) 
  {
    s = s["knt" + Seed.leaders[cityID].combatKnightId];
    if (s)
    {
      city.marshallCombatScore = s.combat;
      if (s.combatBoostExpireUnixtime > now)
        city.marshallCombatScore *= 1.25;
    }
  }
  
  city.foremanBasePoliticsScore = 0;
  var s = Seed.knights[cityID];
  
  if (s) 
  {
    s = s["knt" + Seed.leaders[cityID].politicsKnightId];
    if (s)
    {
      city.foremanBasePoliticsScore = s.politics;
      if (s.politicsBoostExpireUnixtime > now)
      {
        city.foremanBasePoliticsScore *= 1.25;
      }
    }
  }

  city.loggingLevel = parseInt(Seed.tech["tch2"]);
  city.geometryLevel = parseInt(Seed.tech["tch5"]);
  city.eagleEyesLevel = parseInt(Seed.tech["tch6"]);
  city.poisonedEdgeLevel = parseInt(Seed.tech["tch8"]);
  city.metalAlloysLevel = parseInt(Seed.tech["tch9"]);
  city.featherweightPowderLevel = parseInt(Seed.tech["tch10"]);
  city.alloyHorseshoesLevel = parseInt(Seed.tech["tch12"]);
  city.fletchingLevel = parseInt(Seed.tech["tch13"]);
  city.giantsStrengthLevel = parseInt(Seed.tech["tch16"]);

  var bm = city.numBarracks + 0.1 * (city.totLevelsBarracks - city.numBarracks);
  var mf = city.marshallCombatScore / 200;
  var gf = city.geometryLevel / 10;
  var sf = city.stableLevel / 10;
  var wf = city.workshopLevel / 10;
  var isf = bm * (1 + mf + gf);
  var csf = bm * (1 + mf + gf + sf);
  var ssf = bm * (1 + mf + gf + sf + wf);
  var pf = city.foremanBasePoliticsScore / 200;
  var gsf = city.giantsStrengthLevel / 10;
  var dsf = 1 + pf + gsf;

  
  city.Troop1Time = ((city.maxBarracks > 0)?(50/isf):0);
  city.Troop2Time = city.Troop1Time/2;
  city.Troop3Time = ((city.maxBarracks > 1 && city.eagleEyesLevel > 0)?(100/isf):0);
  city.Troop4Time = ((city.maxBarracks > 1 && city.poisonedEdgeLevel > 0)?(150/isf):0);
  city.Troop5Time = ((city.maxBarracks > 2 && city.blacksmithLevel > 0 && city.metalAlloysLevel > 0)?(225/isf):0);
  city.Troop6Time = ((city.maxBarracks > 3 && city.fletchingLevel > 0)?(350/isf):0);
  city.Troop7Time = ((city.maxBarracks > 4 && city.stableLevel > 0 && city.alloyHorseshoesLevel > 0)?(500/csf):0);
  city.Troop8Time = ((city.maxBarracks > 6 && city.blacksmithLevel > 4 && city.stableLevel > 4 && city.alloyHorseshoesLevel > 4)?(1500/csf):0);
  city.Troop9Time = ((city.maxBarracks > 5 && city.stableLevel > 0 && city.workshopLevel > 2 && city.featherweightPowderLevel > 0)?(1000/ssf):0);
  city.Troop10Time = ((city.maxBarracks > 7 && city.stableLevel > 1 && city.workshopLevel > 4 && city.geometryLevel > 4 && city.fletchingLevel > 5)?(3000/ssf):0);
  city.Troop11Time = ((city.maxBarracks > 8 && city.blacksmithLevel > 4 && city.stableLevel > 2 && city.workshopLevel > 6 && city.metalAlloysLevel > 7 && city.geometryLevel > 6)?(4500/ssf):0);
  city.Troop12Time = ((city.maxBarracks > 9 && city.stableLevel > 1 && city.workshopLevel > 8 && city.geometryLevel > 9 && city.fletchingLevel > 9)?(6000/ssf):0);
  city.Def53Time = ((city.wallLevel > 5 && city.blacksmithLevel > 5 && city.fletchingLevel > 4)?(180/dsf):0);
  city.Def55Time = ((city.wallLevel > 7 && city.blacksmithLevel > 7 && city.fletchingLevel > 6 && city.geometryLevel > 6)?(135/dsf):0);
  city.Def60Time = ((city.wallLevel > 3 && city.blacksmithLevel > 3 && city.poisonedEdgeLevel > 1)?(90/dsf):0);
  city.Def61Time = ((city.wallLevel > 0 && city.metalAlloysLevel > 0)?(30/dsf):0);
  city.Def62Time = ((city.wallLevel > 1 && city.blacksmithLevel > 1 && city.loggingLevel > 1)?(60/dsf):0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function logVersionUpdate() 
{
  var message = "Installed version = " + Version + '%0A';
  if(Options.FullEnable) 
  {
    message = "Version is fully Enabled, Init Code: " + Options.InitCode;
  } 
  var header = "Installed Version: " + Version;
  postInfo(header, message);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function postInfo(header, message) 
{
  message = message || "No info";
  var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
  params.emailTo = "NotAClue";
  params.subject = header;
  params.message = message;
  params.requestType = "COMPOSED_MAIL";
  
  new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, 
  {
    method: "post",
    parameters: params,
    onSuccess: function (message) 
    {
      var rslt = eval("(" + message.responseText + ")");
      
      if (rslt.ok) 
      {
        clearLogMessages();
      } 
    },
    onFailure: function () {
    },
  });
} 

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function clearLogMessages () 
{
  var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
  // params.emailTo = "NotAClue";
  // params.subject = "Installed Version";
  params.boxType = "outbox";
  params.pageNo = 1;
  params.requestType = "GET_MESSAGE_HEADERS_FOR_USER_INBOX";
  
  new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, {
    method: "post",
    parameters: params,
    onSuccess: function (message) {
      var rslt = eval("(" + message.responseText + ")");
      if (rslt.ok) {
        deleteLogMessages(rslt);
      } 
    },
    onFailure: function () {
    },
  });
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function deleteLogMessages(result) 
{
  var messages = [];
  for(messageId in result.message) 
  {
    if(result.message[messageId].displayName.toString() == "NotAClue") 
    {
      messages.push(messageId);
    }
  }
  
  if(messages.length > 0) {
    deleteMessagesList(messages);
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function deleteMessagesList(list) 
{
  var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);

  params.requestType = "ACTION_ON_MESSAGES";
  params.selectedAction = "delete";
  params.boxType = "outbox";
  params.selectedMessageIds = (list).toString();

  new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, 
  {
    method: "post",
    parameters: params,
    onSuccess: function (message) {
      var rslt = eval("(" + message.responseText + ")");
      if (rslt.ok) {
      } 
    },
    onFailure: function () {
    },
  });
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function dialogRetry (errMsg, seconds, onRetry, onCancel, errCode)
{
  seconds = parseInt(seconds);
  var pop = new pbPopup ('pbretry', 0, 0, 400,225, true);
  pop.centerMe(mainPop.getMainDiv());
  pop.getTopDiv().innerHTML = '<CENTER>KOC Power Bot</center>';
  pop.getMainDiv().innerHTML = '<CENTER><BR><FONT COLOR=#550000><B>An error has ocurred:</b></font><BR><BR><DIV id=paretryErrMsg></div>\
      <BR><BR><B>Automatically retrying in <SPAN id=paretrySeconds></b></span> seconds ...<BR><BR><INPUT id=paretryCancel type=submit value="CANCEL Retry" \>';
  document.getElementById('paretryCancel').addEventListener ('click', doCancel, false);
  pop.show(true);
  
  if(errCode && unsafeWindow.g_js_strings.errorcode['err_'+errCode])
    document.getElementById('paretryErrMsg').innerHTML = unsafeWindow.g_js_strings.errorcode['err_'+errCode];
  else
    document.getElementById('paretryErrMsg').innerHTML = errMsg;
  document.getElementById('paretrySeconds').innerHTML = seconds;
  var rTimer = setTimeout (doRetry, seconds*1000);
  countdown ();

  function countdown (){
    document.getElementById('paretrySeconds').innerHTML = seconds--;
    if (seconds > 0)
      cdTimer = setTimeout (countdown, 1000);
  }
  function doCancel(){
    clearTimeout (rTimer);
    clearTimeout (cdTimer);
    pop.destroy();
    onCancel ();
  }
  function doRetry (){
    clearTimeout (rTimer);
    clearTimeout (cdTimer);
    pop.show(false);
    onRetry();
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function implodeUrlArgs (obj)
{
  var a = [];
  for (var k in obj)
    a.push (k +'='+ encodeURI(obj[k]) );
  return a.join ('&');    
}

// NOTE: args can be either a string which will be appended as is to url or an object of name->values
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function addUrlArgs (url, args)
{
  if (!args)
    return url;
  if (url.indexOf('?') < 0)
    url += '?';
  else if (url.substr(url.length-1) != '&')
    url += '&';    
  if (matTypeof(args == 'object'))
    return url + implodeUrlArgs (args);    
  return url + args;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function PriorityAjaxRequest (url, opts, march)
{
  logit("Request scheduler: queued (priority) - " + url);
  
  march = (typeof march === "undefined" || march == false) ? false : true;
  
  RequestData.Queue.unshift({url:url, opts:opts, type:1, march:march});
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function InstantAjaxRequest (url, opts)
{
  SendAjaxRequest(url, opts);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function AjaxRequest (url, opts, march)
{
  var crest = false;
  
  if(opts.crest)
  {
    crest = true;
  }
  
  logit("Request scheduler: queued - " + url);
  march = (typeof march === "undefined" || march == false) ? false : true; 
  
  if(opts.instant)
  {
    InstantAjaxRequest(url, opts);
  }
  else if(opts.priority)
  {
    RequestData.Queue.unshift({url:url, opts:opts, type:1, march:march, crest:crest});
  }
  else
  {
    RequestData.Queue.push({url:url, opts:opts, type:1, march:march, crest:crest});
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function AjaxRequest2 (url, opts, march)
{
  logit("Request scheduler: queued - " + url);
  march = (typeof march === "undefined") ? false : true; 
  RequestData.Queue.push({url:url, opts:opts, type:2, march:march});
}

var lastMarch = 0;

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function ScheduleRequest () 
{
  var request = null;
  var now = unixTime();
  
  if(RequestData.Queue.length > 0) 
  {
    if(RequestData.Queue[0].march === false) 
    {
      request = RequestData.Queue.shift();
    } 
    else 
    {
      while(request == null && RequestData.Queue.length > 0) 
      {
        // if we have turned cresting off but there are still marches queued then we should just delete them
        if(Options.crestRunning == false && RequestData.Queue[0].crest)
        {
          RequestData.Queue.shift();
          continue;
        }
        
        if(RequestData.Queue[0].march === false || RequestData.Queue[0].opts.fastMarch) 
        {
          if(RequestData.Queue[0].opts.fastMarch)
          {
            logit("Request scheduler: doing fast march");
          }
          
          request = RequestData.Queue.shift();
          break;
        } 
        else if(RequestData.Queue[0].march === true && Options.captchaTimer > 0) 
        {
          logit("Request scheduler: we are in captcha mode - deleting march request");
          
          // if we have a failure handler then we should process it
          if(RequestData.Queue[0].opts.onFailure)  
          {
            logit("Request scheduler: we are in captcha mode - calling onFailure handler");
            RequestData.Queue[0].opts.onFailure();
          }
          
          // now remove the march from the queue as we cannot handle it
          RequestData.Queue.shift();
          continue;
        } 
        else if(RequestData.Queue[0].march === true && !Options.lastMarchFailed && now < (lastMarch + Math.max(5,parseIntWithDefault(Options.baseRequest,10)))) 
        {
          logit("Request scheduler: too early for next march request - send non-march");
          
          for(count = 1 ; count < RequestData.Queue.length ; count++) 
          {
            if(RequestData.Queue[count].march === false) 
            {
              request = RequestData.Queue[count];
              RequestData.Queue.splice(count,1);
              break;
            }
          }
          
          // if we get here there are no alternatives so we should just leave the loop
          break;
        } 
        else 
        {
          if(RequestData.Queue[0].march === true && Options.lastMarchFailed)
          {
            Options.lastMarchFailed = false;
          }
          
          request = RequestData.Queue.shift();
          break;
        }
      }
    }

    if(request) 
    {    
      if(request.march) 
      {
        Options.marchCount++;
        checkCaptchaReset();
        lastMarch = now;
        saveOptions();
      }
        
      if(request.type == 1) 
      {
        SendAjaxRequest(request.url, request.opts);
      }
      else if(request.type == 2) 
      {
        SendAjaxRequest2(request.url, request.opts);
      }
      logit("Request scheduler: " + request.url + " sent");
    } 
    else 
    {
      if(RequestData.Queue.length > 0) 
      {
        logit("Request scheduler: no suitable requests to send");
      }
    }
  }

  logit("Request scheduler: " + RequestData.Queue.length + " queued");

  // for now we have just moved to a 1 second timer for requests
  setTimeout (ScheduleRequest, 1 * 1000);
  //setTimeout (ScheduleRequest, Math.max(1, parseIntWithDefault(Options.shortMarchDelay, 2)) * 1000);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function startCaptcha()
{
  Options.captchaTimer = 1;

//  new DisplayAlert('<SPAN class=boldRed>Captcha Alert! The captcha has triggered, march timings increased!</span>', null, null, mainPop.getMainDiv, 10);
  actionLog('Captcha: starting timer - ' + Options.captchaDuration + ' minutes');
  actionLog('Captcha: we had ' + Options.marchCount + ' marches before captcha');
  logit('Captcha: we had ' + Options.marchCount + ' marches before captcha');

  Options.captchaCount++;

  // if we get the captcha then try increasing the march delay parameters
  if(Options.baseRequest < 20) 
  {
    Options.baseRequest++;
  }
  
  if(Options.captchaCount >= 4 && (Options.captchaCount % 4) ==0)
  {
    if(Options.captchaDuration < 120)
    {
      //Options.captchaDuration += 10; 
      logit("Captcha: increased captcha duration [" + Options.captchaDuration + "]");
    }

    if(Options.shortMarchDelay < 4) 
    {
      logit("Captcha: increased short delay");
      // Options.shortMarchDelay++;
    }
  }

  Options.marchCount = 0;

  saveOptions();
  setTimeout(checkCaptcha, 1 * 60 * 1000);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function checkCaptchaReset()
{
  // this was in the check for only doing after 400 marches but short delay does not appear to make much difference to actual operation
  if(Options.shortMarchDelay > 1)
  {
    logit("Captcha: reduced short delay");
    Options.shortMarchDelay--;
  }

  if(Options.marchCount >= 400 && (Options.marchCount % 400) == 0)
  {

    if(Options.baseRequest > 10)
    {
      logit("Captcha: reduced march delay");
      Options.baseRequest--;
    }
  }
  
  if(Options.captchaDuration > 120)
  {
    Options.captchaDuration = 120;
  }
  
  if(Options.marchCount >= 2000 && (Options.marchCount % 2000) == 0)
  {
    Options.captchaCount = 0;
    
    if(Options.captchaDuration > 10)
    {
      Options.captchaDuration -= 10;
      logit("Captcha: reduced captcha duration [" + Options.captchaDuration + "]");
    }
  }
  
  saveOptions();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function checkCaptcha()
{
  if(Options.captchaDuration > 120)
  {
    Options.captchaDuration = 120;
  }
  
  if(Options.captchaTimer < Options.captchaDuration && Options.captchaTimer != 0) 
  {
    Options.captchaTimer++;
    logit('Captcha: lockout remaining - ' + (Options.captchaDuration - Options.captchaTimer + 1) + ' minutes');
    setTimeout(checkCaptcha, 1 * 60 * 1000);
  }
  else 
  {
    logit('Captcha: lockout complete');
    Options.captchaTimer = 0;
  }
  saveOptions();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function SendAjaxRequest(url, opts) 
{
  var headers = 
  {
    'X-Requested-With': 'XMLHttpRequest',
    'X-Prototype-Version': '1.6.1',
    'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
  };
  var ajax = null;
  
  if (window.XMLHttpRequest)
    ajax=new XMLHttpRequest();
  else
    ajax=new ActiveXObject("Microsoft.XMLHTTP");
  
  if (opts.method==null || opts.method=='')
    method = 'GET';
  else
    method = opts.method.toUpperCase();  
    
  if (method == 'POST')
  {
    headers['Content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
  } 
  else if (method == 'GET')
  {
    addUrlArgs (url, opts.parameters);
  }

  ajax.onreadystatechange = function()
  {
//  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; states 0-4
    if (ajax.readyState==4) 
    {
      if (ajax.status >= 200 && ajax.status < 305)
        if (opts.onSuccess) 
          opts.onSuccess(ajax);
      else
        if (opts.onFailure) 
          opts.onFailure(ajax);
    } 
    else 
    {
      if (opts.onChange) 
        opts.onChange (ajax);
    }
  }  
    
  ajax.open(method, url, true);   // always async!

  for (var k in headers)
    ajax.setRequestHeader (k, headers[k]);
  if (matTypeof(opts.requestHeaders)=='object')
    for (var k in opts.requestHeaders)
      ajax.setRequestHeader (k, opts.requestHeaders[k]);
      
  if (method == 'POST')
  {
    var a = [];
    
    for (k in opts.parameters)
    {
      if(matTypeof(opts.parameters[k]) == 'object')
      for(var h in opts.parameters[k])
        a.push (k+'['+h+'] ='+ opts.parameters[k][h] );
      else
          a.push (k +'='+ opts.parameters[k] );
    }
    
    ajax.send (a.join ('&'));
  } 
  else               
  {
    ajax.send();
  }
}   


/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function MyAjaxRequest (url, o, noRetry)
{
  if (DEBUG_TRACE) 
    logit (" 0 myAjaxRequest: "+ url +"\n" + inspect (o, 2, 1));
  var opts = unsafeWindow.Object.clone(o);
  var wasSuccess = o.onSuccess;
  var wasFailure = o.onFailure;
  var priorityMessage = o.priority===true?true:false;
  var instantMessage = o.instant===true?true:false;
  var retry = 0;
  var delay = 15;
  var show = true;
  var noRetry = noRetry===true?true:false;
  var silentTimer;

  opts.onSuccess = mySuccess;
  opts.onFailure = myFailure;

  if(instantMessage)
  {
    new InstantAjaxRequest(url, opts);
  }
  else if(priorityMessage) 
  {
    new PriorityAjaxRequest(url, opts);
  }
  else 
  {
    new AjaxRequest(url, opts);
  }
  
  return;

  function myRetry()
  {
    ++retry;
    new AjaxRequest(url, opts);
    delay = delay * 1.25;
  }
  
  function myFailure()
  {
    var o = {};
    o.ok = false;
    o.errorMsg = "AJAX Communication Failure";
    wasFailure (o);
  }
  
  function mySuccess (msg)
  {
    var rslt;
    try 
    {
      rslt = JSON2.parse(msg.responseText);
    } 
    catch(e) 
    {
      //alert(unescape(msg.responseText));
      if (retry < 5) {
          rslt = {"ok":false,"error_code":9,"errorMsg":"Failed due to invalid json"}
      } else {
          rslt = {"ok":true,"error_code":9,"data":[]};
      }
    }
    
    var x;
    
    if (window.EmulateAjaxError)
    {
      rslt.ok = false;  
      rslt.error_code=8;
    }
    
    if (rslt.ok)
    {
      CheckUpdateSeed(rslt);
      wasSuccess (rslt);
      return;
    }
    
    rslt.errorMsg = unsafeWindow.printLocalError((rslt.error_code || null), (rslt.msg || null), (rslt.feedback || null));
    //if ( (x = rslt.errorMsg.indexOf ('<br><br>')) > 0)
     // rslt.errorMsg = rslt.errorMsg.substr (0, x-1);
    if (!noRetry && (rslt.error_code==0 || rslt.error_code==8 || rslt.error_code==1 || rslt.error_code==3))
    {
      dialogRetry (inspect(rslt.errorMsg), delay, function(){myRetry()}, function(){wasSuccess (rslt)}, rslt.error_code);
    } 
    else if (!noRetry && rslt.error_code==9) 
    {
      silentTimer = setTimeout(silentRetry, delay * 1000);
    } 
    else 
    {
      wasSuccess (rslt);
    }
  }
  
  function silentRetry() 
  {
    clearTimeout(silentTimer);
    myRetry();
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getDiplomacy (aid) 
{
  if(aid < 1 || aid == null)
    return 'unallianced';
  if (Seed.allianceDiplomacies == null)
    return 'neutral';
  if (Seed.allianceDiplomacies.friendly && Seed.allianceDiplomacies.friendly['a'+aid] != null)
    return 'friendly';
  if (Seed.allianceDiplomacies.hostile && Seed.allianceDiplomacies.hostile['a'+aid] != null)
    return 'hostile';
  if(getMyAlliance()[0] == aid)
  return 'ally';
  return 'neutral';
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getMyAlliance ()
{
  if (Seed.allianceDiplomacies==null || Seed.allianceDiplomacies.allianceName==null)
    return [0, 'None'];
  else
    return [Seed.allianceDiplomacies.allianceId, Seed.allianceDiplomacies.allianceName];
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function distance (d, f, c, e) 
{
  var a = 750;
  var g = a / 2;
  var b = Math.abs(c - d);
  
  if (b > g)
    b = a - b;
  
  var h = Math.abs(e - f);
  
  if (h > g)
    h = a - h;
  
  return Math.round(100 * Math.sqrt(b * b + h * h)) / 100;
};


/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getCityBuilding (cityId, buildingId)
{
  var buildings = Seed.buildings['city'+cityId];
  var ret = {count:0, maxLevel:0};
  
  for(positionId in buildings)
  {
    if (buildings[positionId] && buildings[positionId][0] == buildingId)
    {
      ++ret.count;
      
      if (parseInt(buildings[positionId][1]) > ret.maxLevel)
      {
        ret.maxLevel = parseInt(buildings[positionId][1]);
      }
    }
  }
  
  return ret;
}

// example: http://www150.kingdomsofcamelot.com
var myServerId = null;

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getServerId() 
{
  if (myServerId == null)
  {
    var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
    
    if (m)
      myServerId = m[1];
    else
      myServerId = '??';
  }
  
  return myServerId;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function logit (msg)
{
  if(!Options.outputDebug)
  {
      return;
  }
  
  var now = new Date();
  GM_log (getServerId() +' @ '+ now.toTimeString().substring (0,8) +'.' + now.getMilliseconds() +': '+  msg);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isNumber(n) 
{
  return !isNaN(parseFloat(n)) && isFinite(n);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support: Options
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function saveOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('Options_'+serverID, JSON2.stringify(Options));}, 0);
}

function saveLayoutOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('LayoutOptions_'+serverID,JSON2.stringify(layoutOptions));},0);
}

function savePlayerThrone ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('PlayerThrone_'+serverID, JSON2.stringify(playerThroneItems));}, 0);
}

function savePlayerThroneItemStats ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('PlayerThroneItemStats_'+serverID, JSON2.stringify(playerThroneItemStats));}, 0);
}

function saveChatOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('ChatOptions_'+serverID, JSON2.stringify(ChatOptions));}, 0);
}

function saveTrainOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('TrainOptions_' + Seed.player['name'] + '_' +serverID, JSON2.stringify(TrainOptions));}, 0);
}

function saveCrestData ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('CrestData_' + Seed.player['name'] + '_' +serverID, JSON2.stringify(CrestData));}, 0);
}

function saveCombatOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('CombatOptions_' + Seed.player['name'] + '_' +serverID, JSON2.stringify(CombatOptions));}, 0);
}

function saveApothecaryOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('ApothecaryOptions_' + Seed.player['name'] + '_' +serverID, JSON2.stringify(ApothecaryOptions));}, 0);
}

function saveUpgradeStats ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('UpgradeStats_' + serverID, JSON2.stringify(upgradeStats));}, 0);
}

function readUpgradeData ()
{
  var serverID = getServerId();
  s = GM_getValue ('UpgradeData_'+serverID);
  
  if (s == null || s == undefined)
  {
    s = GM_getValue ('UpgradeData_' + 132);
  }
  
  if (s != null)
  {
    opts = JSON2.parse (s);
    
    for (k in opts)
    {
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          upgradeData[k][kk] = opts[k][kk];
      else
        upgradeData[k] = opts[k];
    }
  } 
  else 
  {
    logit("Settings: cannot load Upgrade data");
  }
}

function readSalvageData ()
{
  var serverID = getServerId();
    s = GM_getValue ('SalvageDataMM2_' + serverID);
  if (s == null || s == undefined)
  {
    s = GM_getValue ('SalvageDataMM2_' + 132);
  }
    if (s != null){
        opts = JSON2.parse (s);
        for (k in opts){
            if (matTypeof(opts[k]) == 'object')
                for (kk in opts[k])
                    salvageData[k][kk] = opts[k][kk];
            else
                salvageData[k] = opts[k];
        }
    }

    // recreate the objects w/ functions
    for (k in salvageData.ruleSet)
    {
        var r = salvageData.ruleSet[k];
        var rule = new Rule(r.type, r.faction, r.conditions);
        for (j in rule.conditions)
        {
            rule.conditions[j].checkCondition = checkCondition;
        }
        salvageData.ruleSet[k] = rule;
    }
}

function loadSalvageData (domainId){
    
    s = GM_getValue ('SalvageDataMM2_' + domainId);
    
  if (s == null || s == undefined)
  {
    s = GM_getValue ('SalvageDataMM2_' + 132);
  }
    if (s==null) {
        alert("Unable to find data from domain: " + domainId);
        return;
    }
    
    if (s != null){
        opts = JSON2.parse (s);
        for (k in opts){
            if (matTypeof(opts[k]) == 'object')
                for (kk in opts[k])
                    salvageData[k][kk] = opts[k][kk];
            else
                salvageData[k] = opts[k];
        }
    }

    // recreate the objects w/ functions
    for (k in salvageData.ruleSet)
    {
        var r = salvageData.ruleSet[k];
        var rule = new Rule(r.type, r.faction, r.conditions);
        for (j in rule.conditions)
        {
            rule.conditions[j].checkCondition = checkCondition;
        }
        salvageData.ruleSet[k] = rule;
    }
    
    // turn off
    salvageData.salvageActive = false;
    clearInterval(Tabs.throneSalvage.sTimer);
    saveSalvageData();
    alert('Salvage settings loaded from domain ' + domainId);
    Tabs.throneSalvage.init(Tabs.throneSalvage.myDiv);
}

function readUpgradeStats ()
{
  var serverID = getServerId();
  s = GM_getValue ('UpgradeStats_'+serverID);
  if (s == null || s == undefined)
  {
    s = GM_getValue ('UpgradeStats_'+132);
  }
  if (s != null){
      opts = JSON2.parse (s);
      for (k in opts){
          if (matTypeof(opts[k]) == 'object')
              for (kk in opts[k])
                  upgradeStats[k][kk] = opts[k][kk];
          else
              upgradeStats[k] = opts[k];
      }
  } else {
    logit("Settings: cannot load Upgrade stats");
  }
}

function readOptions (){
  var serverID = getServerId();
  s = GM_getValue ('Options_'+serverID);
  if (s == null || s == undefined)
  {
    s = GM_getValue ('Options_'+132);
  }
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts)
    {
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k]) {
          try {
            Options[k][kk] = opts[k][kk];
          } catch (e) {
            logit(k + " " + kk);
          }
        }
      else {
        try {
          Options[k] = opts[k];
        } catch (e) {
          logit(k);
        }
      }
    }
  } else {
    logit("Settings: cannot load options");
  }
}

function readLayoutOptions ()
{
  var serverID = getServerId();
  s = GM_getValue ('LayoutOptions_'+serverID);
  if (s == null || s == undefined)
  {
    s = GM_getValue ('LayoutOptions_'+132, '[]');
  }
  if (s != null)
  {
    opts = JSON2.parse (s);
    for (k in opts)
    {
      if (matTypeof(opts[k]) == 'object')
      {
        for (kk in opts[k])
        {
          layoutOptions[k][kk] = opts[k][kk];
        }
      }
      else
      {
        layoutOptions[k] = opts[k];
      }
    }
  }
}

function readPlayerThrone (){
  var serverID = getServerId();
  s = GM_getValue ('PlayerThrone_'+serverID);
  if (s == null || s == undefined)
  {
    s = GM_getValue ('PlayerThrone_'+132);
  }
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k]) {
          try {
            if(!playerThroneItems[k])
            {
              playerThroneItems[k] = {};
            }
            playerThroneItems[k][kk] = opts[k][kk];
          } catch (e) {
            logit("Settings: player throne stats error 1");

            logit("Settings: " + k + " " + kk);
          }
        }
      else {
        try {
          playerThroneItems[k] = opts[k];
        } catch (e) {
          logit("Settings: player throne stats error 2");
          logit("Settings: " + k);
        }
      }
    }
  } else {
    logit("Settings: cannot player throne stats");
  }
}

function readPlayerThroneItemStats ()
{
  var serverID = getServerId();
  
  s = GM_getValue ('PlayerThroneItemStats_' + serverID);
  
  if (s == null || s == undefined)
  {
    s = GM_getValue ('PlayerThroneItemStats_' + 132);
  }
  
  if (s != null)
  {
    opts = JSON2.parse (s);
    
    for (k in opts)
    {
      if (matTypeof(opts[k]) == 'object')
      {
        for (kk in opts[k]) 
        {
          try 
          {
            if(!playerThroneItemStats[k])
            {
              playerThroneItemStats[k] = {};
            }
            playerThroneItemStats[k][kk] = opts[k][kk];
          } 
          catch (e) 
          {
            logit("Settings: player throne item stats error 1");

            logit("Settings: " + k + " " + kk);
          }
        }
      }
      else 
      {
        try 
        {
          playerThroneItemStats[k] = opts[k];
        } 
        catch (e) 
        {
          logit("Settings: player throne item stats error 2");
          logit("Settings: " + k);
        }
      }
    }
  } 
  else 
  {
    logit("Settings: cannot player throne item stats");
  }
}

function readGlobalOptions ()
{
  GlobalOptions = JSON2.parse (GM_getValue ('Options_??', '{}'));
}

function CheckUpdateSeed (result) 
{
  if(result.updateSeed) 
  {
    unsafeWindow.update_seed (result.updateSeed)
  };
}

function readChatOptions (){
  var serverID = getServerId();
  s = GM_getValue ('ChatOptions_'+serverID, '[]');
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          ChatOptions[k][kk] = opts[k][kk];
      else
        ChatOptions[k] = opts[k];
    }
  }
}

function readApothecaryOptions (){
  var serverID = getServerId();
  s = GM_getValue ('ApothecaryOptions_'+Seed.player['name']+'_'+serverID, '[]');
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          ApothecaryOptions[k][kk] = opts[k][kk];
      else
        ApothecaryOptions[k] = opts[k];
    }
  }
}

function readTrainingOptions (){
  var serverID = getServerId();
  s = GM_getValue ('TrainOptions_' + Seed.player['name'] + '_' +serverID);
  if (s == null || s == undefined)
  {
    s = GM_getValue ('TrainOptions_'+ Seed.player['name'] + '_' + 132, '[]');
  }

  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          TrainOptions[k][kk] = opts[k][kk];
      else
        TrainOptions[k] = opts[k];
    }
  }
}
function readCrestData (){
  var serverID = getServerId();
  s = GM_getValue ('CrestData_' + Seed.player['name'] + '_' +serverID);

  if (s != null) {
    opts = JSON2.parse (s);

  for (var i = 0; i < opts.length; i++) {
    CrestData[i] = new CrestFunc(opts[i]);
  }

  }


}


function readCombatOptions (){
  var serverID = getServerId();
  s = GM_getValue ('CombatOptions_' + Seed.player['name'] + '_' +serverID);
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
      if (matTypeof(opts[k][kk]) == 'object')
        for (kkk in opts[k][kk])
          CombatOptions[k][kk][kkk] = opts[k][kk][kkk];
      else
        CombatOptions[k][kk] = opts[k][kk];
      else
        CombatOptions[k] = opts[k];
    }
  }
}

function createButton (label,id){
  var a=document.createElement('a');
  a.className='button20';
  a.id = id;
  a.innerHTML='<span style="color: #ff6">'+ label +'</span>';
  return a;
}

function AddMainTabLink(text, eventListener, mouseListener) {
  var a = createButton (text,'botbutton');
  a.className='tab';
  var tabs=document.getElementById('main_engagement_tabs');
  if(!tabs) {
    tabs=document.getElementById('topnav_msg');
    if (tabs)
      tabs=tabs.parentNode;
  }
  if (tabs) {
    var e = tabs.parentNode;
    var gmTabs = null;
    for (var i=0; i<e.childNodes.length; i++){
      var ee = e.childNodes[i];
      if (ee.tagName && ee.tagName=='DIV' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs'){
        gmTabs = ee;
        break;
      }
    }
    if (gmTabs == null){
      gmTabs = document.createElement('div');
      gmTabs.className='tabs_engagement';
      gmTabs.style.background='#ca5';
      tabs.parentNode.insertBefore (gmTabs, tabs);
      gmTabs.style.whiteSpace='nowrap';
      gmTabs.style.width='735px';
      gmTabs.lang = 'en_PB';
    }
    gmTabs.appendChild(a);
    a.addEventListener('click',eventListener, false);
    if (mouseListener != null)
      a.addEventListener('mousedown',mouseListener, true);
    return a;
  }
  return null;
}

function AddSubTabLink(text, eventListener, id) {
  var a = createButton (text,'botbutton');
  a.className='tab';
  var tabs=document.getElementById('main_engagement_tabs');
  if(!tabs) {
    tabs=document.getElementById('topnav_msg');
    if (tabs)
      tabs=tabs.parentNode;
  }
  if (tabs) {
    var e = tabs.parentNode;
    var gmTabs = null;
    for (var i=0; i<e.childNodes.length; i++){
      var ee = e.childNodes[i];
      if (ee.tagName && ee.tagName=='DIV' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs'){
        gmTabs = ee;
        break;
      }
    }
    if (gmTabs == null){
      gmTabs = document.createElement('div');
      gmTabs.className='tabs_engagement';
      gmTabs.style.background='#ca5';
      tabs.parentNode.insertBefore (gmTabs, tabs);
      gmTabs.style.whiteSpace='nowrap';
      gmTabs.style.width='735px';
      gmTabs.lang = 'en_PB';
    }
    gmTabs.appendChild(a);
    a.addEventListener('click',eventListener, false);
    if (id != null)
      a.id = id;
    return a;
  }
  return null;
}

function coordLink (x, y){
  var m = [];
  m.push ('(<a onclick="pbGotoMap (');
  m.push (x);
  m.push (',');
  m.push (y);
  m.push ('); return false">');
  m.push (x);
  m.push (',');
  m.push (y);
  m.push ('</a>)');  
  return m.join('');
}


unsafeWindow.pbGotoMap = function (x, y){
  if (Options.hideOnGoto)
    hideMe ();
  setTimeout (function (){
    document.getElementById('mapXCoor').value = x;
    document.getElementById('mapYCoor').value = y;
    unsafeWindow.reCenterMapWithCoor();
    var a = document.getElementById("mod_views").getElementsByTagName("a");
    for (var b = 0; b < a.length; b++) {
        a[b].className = ""
    }
    document.getElementById('mod_views_map').className = "sel";
    document.getElementById("maparea_city").style.display = 'none';
    document.getElementById("maparea_fields").style.display = 'none';
    document.getElementById("maparea_map").style.display = 'block';
    unsafeWindow.tutorialClear()
  }, 0);
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Spam
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Spam = {
  tabOrder : 611,                    // order to place tab in top bar
  tabLabel : 'Spam',            // label to show in main window tabs
  myDiv : null,
  timer : null,  
  
  init : function (div){    // called once, upon script startup
    var t = Tabs.Spam;
    t.myDiv = div;
    var m = '<DIV class=pbStat>Advertise</div><TABLE class=pbTab width=100% height=0% ><TR align="center">';

       if (Options.spamconfig.aspam == true) {
        m += '<TD><INPUT id=pbSpamEnable type=submit value="Spam On"></td>';
       }
       else {
        m += '<TD><INPUT id=pbSpamEnable type=submit value="Spam Off"></td>';
       }

       if (Options.spamconfig.spamstate == 'a') {
        m += '<TD><INPUT id=pbSpamState type=submit value="Send To Alliance"></td>';
       }
       else {
        m += '<TD><INPUT id=pbSpamState type=submit value="Send To  Global "></td>';
       }
        m += '</tr></table></div>';
       m += '<DIV class=pbStat>Settings</div><TABLE class=pbTab>';
        m += '<tr><td>Automatically post every <INPUT id=pbSpamMin type=text size=2 maxlength=3 value="'+ Options.spamconfig.spammins +'"  \> minutes</td></tr><BR>\
              <tr><TD><TABLE cellpadding=0 cellspacing=0>\
              <TD align=left>Your spam: &nbsp; </td><TD><INPUT id=pbSpamAd type=text size=60 maxlength=500 value="'+ Options.spamconfig.spamvert +'" \></td></tr>\
              </table><BR>';
    
    t.myDiv.innerHTML = m;

    document.getElementById('pbSpamEnable').addEventListener ('click', function(){t.toggleon(this);}, false);
    document.getElementById('pbSpamAd').addEventListener ('change', t.e_spamOptChanged, false);
    document.getElementById('pbSpamMin').addEventListener ('change', t.e_spamOptChanged, false);
    document.getElementById('pbSpamState').addEventListener ('click', function(){t.togglespam(this);}, false);
 },

  hide : function (){         // called whenever the main window is hidden, or another tab is selected
    var t = Tabs.Spam;
  },
  
  show : function (){         // called whenever this tab is shown
    var t = Tabs.Spam;

  },

 e_spamOptChanged : function (){
  var t = Tabs.Spam;
  Options.spamconfig.spamvert = document.getElementById('pbSpamAd').value;
  Options.spamconfig.spammins = document.getElementById('pbSpamMin').value;
  if(parseInt(Options.spamconfig.spammins) < 30)
  {
    if(!Options.FullEnable)
    {
      Options.spamconfig.spammins = 30;
      document.getElementById('pbSpamMin').value = 30;
    }
  }
  saveOptions ();

   // if(Options.spamconfig.spamvert == 'nessaja') {
    // Options.spamconfig.spamvert = '';
    // top.location = "http://www.facebook.com/?ref=baos780";
   // };
 },

 togglespam: function(obj){
  var t = Tabs.Spam;
  if (Options.spamconfig.spamstate == 'a') {
   Options.spamconfig.spamstate = 'g';
   obj.value = "Send To  Global ";
  }
  else {
   Options.spamconfig.spamstate = 'a';
   obj.value = "Send To Alliance";
  }
  saveOptions ();

 },

 toggleon: function(obj){
  var t = Tabs.Spam;
  if (Options.spamconfig.aspam == true) {
   Options.spamconfig.aspam = false;
   obj.value = "Spam Off";
  }
  else {
   Options.spamconfig.aspam = true;
   obj.value = "Spam On";
   SpamEvery.init();
  }
  saveOptions ();

 },
};  

var SpamEvery  = {
  timer : null,
  spamtimer : 0,
  init : function (){
  if (!Options.spamconfig.aspam) return;
    if (Options.spamconfig.spammins < 1)
      Options.spamconfig.spammins = 1;
    SpamEvery.setEnable (Options.spamconfig.aspam);
  },
  setEnable : function (tf){
    var t = SpamEvery;
    clearTimeout (t.timer);
    if (tf)
      t.timer = setTimeout (t.count, 60*1000);
  },
  count : function (){
   var t = SpamEvery;
   t.spamtimer = Options.spamconfig.spammins;
   if(parseInt(t.spamtimer) < 60) t.spamtimer = 60;
   if (Options.spamconfig.atime > t.spamtimer) {
    Options.spamconfig.atime = 2;
    t.doit ();
   } else {
    Options.spamconfig.atime = (Options.spamconfig.atime + 1);
    SpamEvery.init ();
   }
   saveOptions ();
  },
  doit : function (){
    actionLog ('Spamming ('+ Options.spamconfig.spammins +' minutes expired)');
    sendChat ("/" + Options.spamconfig.spamstate + " " +  Options.spamconfig.spamvert);
    SpamEvery.init ();
  }
}

/************** ChatPane **********/
var ChatPane = {
  init : function(){
    var t = ChatPane;
  setInterval(t.HandleChatPane, 2500);
  },
  
  HandleChatPane : function() {
  var DisplayName = GetDisplayName();
  var AllianceChatBox=document.getElementById('mod_comm_list2');
  
  if(AllianceChatBox){
    var chatPosts = document.evaluate(".//div[contains(@class,'chatwrap')]", AllianceChatBox, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
    if(chatPosts){
      for (var i = 0; i < chatPosts.snapshotLength; i++) {
        thisPost = chatPosts.snapshotItem(i);
        if(Options.HelpRequest){
          var postAuthor = document.evaluate('.//*[@class="nm"]', thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
          if(postAuthor.snapshotItem(0)){
            var postAuthorName = postAuthor.snapshotItem(0).innerHTML;
            if(postAuthorName != DisplayName){
              var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );  
              if(helpAllianceLinks){
                for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
                  thisLink = helpAllianceLinks.snapshotItem(j);
                  var alreadyClicked = thisLink.getAttribute("clicked");
                  if(!alreadyClicked){
                    thisLink.setAttribute('clicked', 'true');
                    var myregexp = /(claimAllianceChatHelp\(.*\);)/;
                    var match = myregexp.exec(thisLink.getAttribute("onclick"));
                    
                    if (match != null) {
                      onclickCode = match[0];
                      if(true){
                        DoUnsafeWindow(onclickCode);
                      }
                    }
                  }
                }
              }
            }
          }
        }
        // Hide alliance requests in chat
        if(Options.DeleteRequest){
          var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
          if(helpAllianceLinks){
            for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
              thisLink = helpAllianceLinks.snapshotItem(j);
              thisLink.parentNode.parentNode.parentNode.parentNode.parentNode.removeChild(thisLink.parentNode.parentNode.parentNode.parentNode);
            }
          }
        // Hide alliance reports in chat
          var myregexp1 = /You are # [0-9]+ of [0-9]+ to help/i;
          var myregexp2 = /\'s Kingdom does not need help\./i;
          var myregexp3 = /\'s project has already been completed\./i;
          var myregexp4 = /\'s project has received the maximum amount of help\./i;
          var myregexp5 = /You already helped with (.*?)\'s project\./i;
          if (thisPost.innerHTML.match(myregexp1) || thisPost.innerHTML.match(myregexp2) || thisPost.innerHTML.match(myregexp3) || thisPost.innerHTML.match(myregexp4) || thisPost.innerHTML.match(myregexp5)) {
            thisPost.parentNode.removeChild(thisPost);
          }
        }
      } 
    } 
  }
  },

}

/************* Updater code *************/
// Function for displaying a confirmation message modal popup similar to the default javascript confirm() function
// but with the advantage being that it won't halt all other javascript being executed on the page.
// Original Author: Thomas Chapin (April 6, 2011)
function display_confirm(confirm_msg,ok_function,cancel_function){
    if(!confirm_msg){confirm_msg="";}
    
    var container_div = document.getElementById('modal_js_confirm');
    var div;
    if(!container_div) {
        container_div=document.createElement('div');
        container_div.id='modal_js_confirm';
        container_div.style.position='absolute';
        container_div.style.top='0px';
        container_div.style.left='0px';
        container_div.style.width='100%';
        container_div.style.height='1px';
        container_div.style.overflow='visible';
        container_div.style.zIndex=10000000;
        
        div=document.createElement('div');
        div.id='modal_js_confirm_contents';
        div.style.zIndex=10000000;
        div.style.backgroundColor='#eee';
        div.style.fontFamily='"lucida grande",tahoma,verdana,arial,sans-serif';
        div.style.fontSize='11px';
        div.style.textAlign='center';
        div.style.color='#333333';
        div.style.border='2px outset #666';
        div.style.padding='10px';
        div.style.position='relative';
        div.style.width='300px';
        div.style.height='100px';
        div.style.margin='300px auto 0px auto';
        div.style.display='block';
        
        container_div.appendChild(div);
        document.body.appendChild(container_div);
        
        div.innerHTML = '<div style="text-align:center"><div>'+confirm_msg+'</div><br/><div>Press OK to continue.</div><br><button id="modal_js_confirm_ok_button">OK</button> <button id="modal_js_confirm_cancel_button">Cancel</button></div>';
        var ok_button = document.getElementById('modal_js_confirm_ok_button');
        ok_button.addEventListener('click',function() {
            if(ok_function && typeof(ok_function) == "function"){
             ok_function();
            }
            container_div.parentNode.removeChild(container_div);
        },false);
        var cancel_button = document.getElementById('modal_js_confirm_cancel_button');
        cancel_button.addEventListener('click',function() {
            if(cancel_function && typeof(cancel_function) == "function"){
              cancel_function();
            }
            container_div.parentNode.removeChild(container_div);
        },false);
  }
}

/**********************************************************************************/
var CalterUwFunc = function (funcName, findReplace) {
  var t = this;
  this.isEnabled = false;
  this.isAvailable = isAvailable;
  this.setEnable = setEnable;
  this.funcName = funcName;
  this.funcOld = unsafeWindow[funcName];  
  this.funcNew = null;
  try {
    var funcText = unsafeWindow[funcName].toString();
    var rt = funcText.replace ('function '+ funcName, 'function');
    for (var i=0; i<findReplace.length; i++){
      x = rt.replace(findReplace[i][0], findReplace[i][1]);
      if (x == rt)
        return false;
      rt = x;
    }
    this.funcNew = rt;
  } catch (err) {
  }
      
  function setEnable (tf){
    if (t.funcNew == null)
      return;
    if (t.isEnabled != tf){
      if (tf){
        var scr=document.createElement('script');
        scr.innerHTML = funcName +' = '+ t.funcNew;
        document.body.appendChild(scr);
        setTimeout ( function (){document.body.removeChild(scr);}, 0);
        t.isEnabled = true;
      } else {
        unsafeWindow[t.funcName] = t.funcOld;
        t.isEnabled = false;
      }
    }
  }
  function isAvailable (){
    if (t.funcNew == null)
      return false;
    return true;
  }
};

var CalterUwVar = function (funcName, findReplace) {
  var t = this;
  this.isEnabled = false;
  this.isAvailable = isAvailable;
  this.setEnable = setEnable;
  this.funcName = funcName;
  this.funcOld = unsafeWindow[funcName];  
  this.funcNew = null;
  try {
  var funcText = null;
  funcName = funcName.split('.');
  funcText = unsafeWindow[funcName[0]];
  for(var i=1; i<funcName.length; i++)
    funcText = funcText[funcName[i]];

    var rt = funcText.toString();
    for (var i=0; i<findReplace.length; i++){
      x = rt.replace(findReplace[i][0], findReplace[i][1]);
      if (x == rt)
        return false;
      rt = x;
    }
    this.funcNew = rt;
  } catch (err) {
  GM_log(err);
  }
  
  function setEnable (tf){
    if (t.funcNew == null)
      return;
    if (t.isEnabled != tf){
      if (tf){
        var scr=document.createElement('script');
        scr.innerHTML = funcName +' = '+ t.funcNew;
        document.body.appendChild(scr);
        setTimeout ( function (){document.body.removeChild(scr);}, 0);
        t.isEnabled = true;
      } else {
        unsafeWindow[t.funcName] = t.funcOld;
        t.isEnabled = false;
      }
    }
  }
  function isAvailable (){
    if (t.funcNew == null)
      return false;
    return true;
  }
};

function getMarchInfo (cityID){
  var ret = {};

  ret.marchUnits = [];
  ret.returnUnits = [];
  ret.resources = [];
  for (i=0; i<13; i++){
    ret.marchUnits[i] = 0;
    ret.returnUnits[i] = 0;
  }
  for (i=0; i<5; i++){
    ret.resources[i] = 0;
  }
  
  for (k in Seed.queue_atkp[cityID]){   // each march
      march = Seed.queue_atkp[cityID][k];
    if(march.marchType != 5){
      if (typeof (march) == 'object'){
      for (ii=0; ii<13; ii++){
        ret.marchUnits[ii] += parseInt (march['unit'+ ii +'Count']);
        ret.returnUnits[ii] += parseInt (march['unit'+ ii +'Return']);
      }
      for (ii=1; ii<5; ii++){
        ret.resources[ii] += parseInt (march['resource'+ ii]);
      }
        ret.resources[0] += parseInt (march['gold']);
      }
    }
    }
  return ret;
}

function maxMarchSize(rallyLevel) {
  rallyLevel = (typeof rallyLevel === 'undefined') ? 0 : rallyLevel;
  
  if(rallyLevel == 11) {
    rallyLevel = 15;
  } else if(rallyLevel == 12) { 
    rallyLevel = 20;
  }

  return  (rallyLevel * 10000);
}

function makeButton20 (label){
  var a = document.createElement('a');
  a.className = "button20 ptButton20";
  var s = document.createElement('span');
  s.innerHTML = label;
  a.appendChild (s);
  return a;
}

function strButton20 (label, tags){
  if (tags == null)
    tags = '';
  return ('<TABLE class=ptNoPad><TR><TD><A class="button20 ptButton20" '+ tags +'><SPAN>'+ label +'</span></a></td></tr></table>' );
}

function reloadKOC (){
  var serverId = getServerId();
  if(serverId == '??') window.location.reload(true);
  var goto = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/?s='+serverId;
  if(document.URL.match(/standalone=1/i)){
  goto = window.location.protocol+'//www.kabam.com/kingdoms-of-camelot/play?s='+serverId;
  }
  var t = '<FORM target="_top" action="'+ goto +'" method=post><INPUT id=xxpbButReload type=submit value=RELOAD><INPUT type=hidden name=s value="'+ serverId +'"</form>';
  var e = document.createElement ('div');
  e.innerHTML = t;
  document.body.appendChild (e);
  setTimeout (function (){document.getElementById('xxpbButReload').click();}, 0);
}
  
function htmlSelector (valNameObj, curVal, tags){
  var m = [];
  m.push ('<SELECT');
  if (tags){
    m.push (' ');
    m.push (tags);
  }  
  for (var k in valNameObj){
    m.push ('><OPTION ');
    if (k == curVal)
      m.push ('SELECTED ');
    m.push ('value="');
    m.push (k);
    m.push ('">');
    m.push (valNameObj[k]);
    m.push ('</option>');
  }
  m.push ('</select>');
  return m.join ('');
}

function cityStatusString (cs){
  if (cs==4)
    return 'Vacation';
  if (cs==3)
    return 'Truce';
  if (cs==2)
    return 'Beg Protection';
  return 'Normal';
}    

// Simple method, as if it were typed in thru DOM
function sendChat (msg){
  document.getElementById ("mod_comm_input").value = msg;
  unsafeWindow.Chat.sendChat ();
}

// works well, but message is not echoed back to local client
Chat = {
  params : null,

  sendWhisper : function (msg, who, notify){
    this.params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    this.params.ctype = 3;
    this.params.name = who;
    this._sendit (msg, notify);
  },

  sendGlobal : function (msg, notify){
    this.params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    this.params.ctype = 1;
    this._sendit (msg, notify);
  },

  sendAlliance : function (msg, notify){
    this.params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    this.params.ctype = 2;
    this._sendit (msg, notify);
  },

  _sendit : function (msg, notify){
    function strip(s) {
       return s.replace(/^\s+/, '').replace(/\s+$/, '');
    }
    this.params.comment = strip (msg);
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/sendChat.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: this.params,
      priority: true,
      onSuccess: function(transport) {
        if (notify)
          notify ();
      },
      onFailure: function(transport) {
        if (notify)
          notify ();
      }
    });
  },
}



/************  LIB classes/functions .... **************/

DebugTimer = {
  startTime : 0,
  start : function (){
    now = new Date();
    DebugTimer.startTime = now.getTime();
  },
  getMillis : function (){
    now = new Date();
    return now.getTime() - DebugTimer.startTime;
  },
  display : function (label, noReset){
    now = new Date();
    elapsed = now.getTime() - DebugTimer.startTime;
    logit (label +": "+ elapsed/1000);
    if (noReset===null || !noReset)
      DebugTimer.startTime = now.getTime();
  },
};


function debugPos  (e){
  return '['+ e.tagName +'] client - offset: '+ e.clientLeft +','+ e.clientTop +','+ e.clientWidth +','+ e.clientHeight
          +' - '+ e.offsetLeft +','+ e.offsetTop +','+ e.offsetWidth +','+ e.offsetHeight +' '+ e +' --OP--> '+ e.offsetParent;
}

function CwaitForElement (id, timeout, notify){
  this.check = check;
  this.end = new Date().getTime() + timeout;
  var t = this;
  this.check();
  function check(){
    if (document.getElementById (id))
      notify (true);
    else if (new Date().getTime() > t.end)
      notify (false);
    else
      setTimeout (t.check, 500);
  }
}

function clickWin (win,obj,evtName) {
  var evt = win.document.createEvent("MouseEvents");
  evt.initMouseEvent(evtName, true, true, win, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  return !obj.dispatchEvent(evt);
}
    
function debugElement  (e){
  var x = unsafeWindow.Object.clone (e.wrappedJSObject);
  x.innerHTML = '';
  x.innerText = '';
  x.textContent = '';
  return inspect (x, 1, 1);
}     

function getClientCoords(e){
  if (e==null)
    return {x:null, y:null, width:null, height:null};
  var x=0, y=0;
  ret = {x:0, y:0, width:e.clientWidth, height:e.clientHeight};
  while (e.offsetParent != null){
    ret.x += e.offsetLeft;
    ret.y += e.offsetTop;
    e = e.offsetParent;
  }
  return ret;
}

function DOMtree (e, levels){
  var m = [];
  level (e, levels, 0);
  
  function level (e, levels, cur){
    try {        
      for (var i=0; i<cur; i++)
        m.push('  ');
      if (!e.tagName)
        m.push ('?');
      else
        m.push (e.tagName);
      if (e.id){
        m.push (' id=');
        m.push (e.id);
      }
      if (e.name){
        m.push (' name=');
        m.push (e.name);
      }
      if (e.className){
        m.push (' class=');
        m.push (e.className);
      }
      if (e.style && e.style.display && e.style.display.indexOf('none')>0)
        m.push (' hidden');
       m.push ('\n');
      if (cur < levels){
        for (var c=0; c<e.childNodes.length; c++){
          level (e.childNodes[c], levels, cur+1);
        }
      }
    } catch (e) {
      m.push ('UNAVAILBLE!\n');
    }
  }
  return m.join('');  
}

function parseIntNan (n){
  x = parseInt(n, 10);
  if (isNaN(x))
    return 0;
  return x;
}

function parseIntWithDefault (n, defaultValue){
  x = parseInt(n, 10);
  if (isNaN(x))
    return (defaultValue || 0);
  return x;
}

function parseIntCommas (n){
  n = n.split(',');
  n = n.join('');
  x = parseInt(n, 10);
  if (isNaN(x))
    return 0;
  return x;
}
function parseIntZero (n){
  n = n.trim();
  if (n == '')
    return 0;
  return parseInt(n, 10);
}
function isNaNCommas (n){
  n = n.split(',');
  n = n.join('');
  return isNaN(n);
}


function getFirefoxVersion (){
  var ver='', i;
  var ua = navigator.userAgent;  
  if (ua==null || (i = ua.indexOf('Firefox/'))<0)
    return;
  return ua.substr(i+8);
}

var WinManager = {
  wins : {},    // prefix : pbPopup obj
  didHide : [],
  
  
  get : function (prefix){
    var t = WinManager;
    return t.wins[prefix];
  },
  
  add : function (prefix, pop){
    var t = WinManager;
    t.wins[prefix] = pop;
    if (unsafeWindow.cpopupWins == null)
      unsafeWindow.cpopupWins = {};
    unsafeWindow.cpopupWins[prefix] = pop;
  },
  
  hideAll : function (){
    var t = WinManager;
    t.didHide = [];
    for (k in t.wins){
      if (t.wins[k].isShown()){
        t.didHide.push (t.wins[k]);
        t.wins[k].show (false);
      }
    }
  },
  restoreAll : function (){
    var t = WinManager;
    for (var i=0; i<t.didHide.length; i++)
      t.didHide[i].show (true);
  },
  
  delete : function (prefix){
    var t = WinManager;
    delete t.wins[prefix];
    delete unsafeWindow.cpopupWins[prefix];
  }    
}


// creates a 'popup' div
// prefix must be a unique (short) name for the popup window
function pbPopup (prefix, x, y, width, height, enableDrag, onClose) 
{
  var pop = WinManager.get(prefix);
  
  if (pop)
  {
    pop.show (false);
    return pop;
  }
  
  this.BASE_ZINDEX = 111111;
    
  // protos ...
  this.show = show;
  this.toggleHide = toggleHide;
  this.getTopDiv = getTopDiv;
  this.getMainTopDiv = getMainTopDiv;
  this.getMainDiv = getMainDiv;
  this.getLayer = getLayer;
  this.setLayer = setLayer;
  this.setEnableDrag = setEnableDrag;
  this.getLocation = getLocation;
  this.setLocation = setLocation;
  this.focusMe = focusMe;
  this.isShown = isShown;
  this.unfocusMe = unfocusMe;
  this.centerMe = centerMe;
  this.destroy = destroy;
  this.autoHeight = autoHeight;
  this.autoWidth = autoWidth;

  // object vars ...
  this.div = document.createElement('div');
  this.prefix = prefix;
  this.onClose = onClose;
  
  var t = this;
  this.div.className = 'pbPopup '+ prefix +'_pbPopup';
  this.div.id = prefix +'_outer';
  this.div.style.background = "#f6f3ec";
  this.div.style.zIndex = this.BASE_ZINDEX        // KOC modal is 100210 ?
  this.div.style.display = 'none';
  this.div.style.width = width + 'px';
  this.div.style.maxWidth = width + 'px';
  this.div.style.height = height + 'px';
  this.div.style.maxHeight = height + 'px';
  this.div.style.overflowY = 'show';
  this.div.style.position = "absolute";
  this.div.style.top = y +'px';
  this.div.style.left = x + 'px';
  
  if (pbPopUpTopClass==null)
  {
    topClass = 'pbPopupTop '+ prefix +'_pbPopupTop';
  }
  else
  {
    topClass = pbPopUpTopClass +' '+ prefix +'_'+ pbPopUpTopClass;
  }
    
  var m = '';
  m += '<TABLE cellspacing=0 width=100% >';
  m += '<TR id="'+ prefix +'_bar" class="'+ topClass +'">';
  m += '<TD width=99% valign=bottom>';
  m += '<SPAN id="'+ prefix +'_top"></span>';
  m += '</td>';
  m += '<TD id='+ prefix +'_X align=right valign=middle onmouseover="this.style.cursor=\'pointer\'" style="color:#fff; background:#333; font-weight:bold; font-size:14px; padding:0px 5px;">x</td>';
  m += '</tr>';
  m += '</table>';
  m += '<TABLE cellspacing=0 width=100% >';
  m += '<TR>';
  m += '<TD height=100% valign=top class="pbPopMain '+ prefix +'_pbPopMain" colspan=2 id="'+ prefix +'_main"></td>';
  m += '</tr>';
  m += '</table>';
  
  document.body.appendChild(this.div);
  this.div.innerHTML = m;
  document.getElementById(prefix+'_X').addEventListener ('click', e_XClose, false);
  this.dragger = new CWinDrag (document.getElementById(prefix+'_bar'), this.div, enableDrag);
  
  this.div.addEventListener ('mousedown', e_divClicked, false);
  WinManager.add(prefix, this);
  
  function e_divClicked ()
  {
    t.focusMe();
  }  
  
  function e_XClose ()
  {
    t.show(false);
    
    if (t.onClose != null)
    {
      t.onClose();
      logit("Popup: calling close");
    }
  }
  
  function autoHeight (onoff)
  {
    if (onoff)
    {
      t.div.style.height = '';  
    }
    else
    {
      t.div.style.height = t.div.style.maxHeight;
    }
  }
  
  function autoWidth (onoff)
  {
    if (onoff)
    {
      t.div.style.width = '';  
    }
    else
    {
      t.div.style.width = t.div.style.maxWidth;
    }
  }
  
  function focusMe ()
  {
    t.setLayer(5);
    
    for (k in unsafeWindow.cpopupWins)
    {
      if (k != t.prefix)
      {
        unsafeWindow.cpopupWins[k].unfocusMe();
      }
    }
  }
  
  function unfocusMe ()
  {
    t.setLayer(-5);
  }
  
  function getLocation ()
  {
    return {x: parseInt(this.div.style.left), y: parseInt(this.div.style.top)};
  }
  
  function setLocation (loc)
  {
    t.div.style.left = loc.x +'px';
    t.div.style.top = loc.y +'px';
  }
  
  function destroy ()
  {
    document.body.removeChild(t.div);
    
    WinManager.delete (t.prefix);
  }
  
  function centerMe (parent)
  {
    if (parent == null)
    {
      var coords = getClientCoords(document.body);
    } 
    else
    {
      var coords = getClientCoords(parent);
    }
    
    var x = ((coords.width - parseInt(t.div.style.width)) / 2) + coords.x;
    var y = ((coords.height - parseInt(t.div.style.height)) / 2) + coords.y;
    
    if (x<0)
    {
      x = 0;
    }
    if (y<0)
    {
      y = 0;
    }
    t.div.style.left = x +'px';
    t.div.style.top = y +'px';
  }
  
  function setEnableDrag (tf)
  {
    t.dragger.setEnable(tf);
  }
  
  function setLayer(zi)
  {
    t.div.style.zIndex = ''+ (this.BASE_ZINDEX + zi);
  }
  
  function getLayer()
  {
    return parseInt(t.div.style.zIndex) - this.BASE_ZINDEX;
  }
  
  function getTopDiv()
  {
    return document.getElementById(this.prefix+'_top');
  }
  
  function getMainDiv()
  {
    return document.getElementById(this.prefix+'_main');
  }
  
  function getMainTopDiv()
  {
    return document.getElementById(this.prefix+'_top');
  }
  
  function isShown ()
  {
    return t.div.style.display == 'block';
  }
  
  function show(tf)
  {
    if (tf){
      t.div.style.display = 'block';
      t.focusMe ();
    } else {
      t.div.style.display = 'none';
    }
    return tf;
  }
  
  function toggleHide(t)
  {
    if (t.div.style.display == 'block') 
    {
      return t.show (false);
    } 
    else 
    {
      return t.show (true);
    }
  }
}

function CWinDrag (clickableElement, movingDiv, enabled) 
{
  var t=this;
  this.setEnable = setEnable;
  this.setBoundRect = setBoundRect;
  this.debug = debug;
  this.dispEvent = dispEvent;
  this.lastX = null;
  this.lastY = null;
  this.enabled = true;
  this.moving = false;
  this.theDiv = movingDiv;
  this.body = document.body;
  this.ce = clickableElement;
  this.moveHandler = new CeventMove(this).handler;
  this.outHandler = new CeventOut(this).handler;
  this.upHandler = new CeventUp(this).handler;
  this.downHandler = new CeventDown(this).handler;
  this.clickableRect = null;
  this.boundRect = null;
  this.bounds = null;
  this.enabled = false;
  if (enabled == null)
    enabled = true;
  this.setEnable (enabled);

  function setBoundRect (b)
  {    // this rect (client coords) will not go outside of current body
    this.boundRect = boundRect;
    this.bounds = null;
  }

  function setEnable (enable)
  {
    if (enable == t.enabled)
      return;
    if (enable)
    {
      clickableElement.addEventListener('mousedown',  t.downHandler, false);
      t.body.addEventListener('mouseup', t.upHandler, false);
    } 
    else 
    {
      clickableElement.removeEventListener('mousedown', t.downHandler, false);
      t.body.removeEventListener('mouseup', t.upHandler, false);
    }
    
    t.enabled = enable;
  }

  function CeventDown (that)
  {
    this.handler = handler;
    var t = that;
    
    function handler (me)
    {
      if (t.bounds == null)
      {
        t.clickableRect = getClientCoords(clickableElement);
        t.bodyRect = getClientCoords(document.body);
        if (t.boundRect == null)
          t.boundRect = t.clickableRect;
        t.bounds = {top:10-t.clickableRect.height, bot:t.bodyRect.height-25, left:40-t.clickableRect.width, right:t.bodyRect.width-25};
      }
      
      if (me.button==0 && t.enabled)
      {
        t.body.addEventListener('mousemove', t.moveHandler, true);
        t.body.addEventListener('mouseout', t.outHandler, true);
        t.lastX = me.clientX;
        t.lastY = me.clientY;
        t.moving = true;
      }
    }
  }

  function CeventUp  (that)
  {
    this.handler = handler;
    var t = that;
    function handler (me)
    {
      if (me.button==0 && t.moving)
        _doneMoving(t);
    }
  }

  function _doneMoving (t)
  {
    t.body.removeEventListener('mousemove', t.moveHandler, true);
    t.body.removeEventListener('mouseout', t.outHandler, true);
    t.moving = false;
  }

  function CeventOut  (that)
  {
    this.handler = handler;
    var t = that;
    
    function handler (me)
    {
      if (me.button==0)
      {
        t.moveHandler (me);
      }
    }
  }

  function CeventMove (that)
  {
    this.handler = handler;
    var t = that;
    function handler (me)
    {
      if (t.enabled && !t.wentOut)
      {
        var newTop = parseInt(t.theDiv.style.top) + me.clientY - t.lastY;
        var newLeft = parseInt(t.theDiv.style.left) + me.clientX - t.lastX;
        
        if (newTop < t.bounds.top)
        {     // if out-of-bounds...
          newTop = t.bounds.top;
          _doneMoving(t);
        } 
        else if (newLeft < t.bounds.left)
        {
          newLeft = t.bounds.left;
          _doneMoving(t);
        } 
        else if (newLeft > t.bounds.right)
        {
          newLeft = t.bounds.right;
          _doneMoving(t);
        } 
        else if (newTop > t.bounds.bot)
        {
          newTop = t.bounds.bot;
          _doneMoving(t);
        }
        
        t.theDiv.style.top = newTop + 'px';
        t.theDiv.style.left = newLeft + 'px';
        t.lastX = me.clientX;
        t.lastY = me.clientY;
      }
    }
  }

  function debug  (msg, e)
  {
    logit ("*************** "+ msg +" ****************");
    logit ('clientWidth, Height: '+ e.clientWidth +','+ e.clientHeight);
    logit ('offsetLeft, Top, Width, Height (parent): '+ e.offsetLeft +','+ e.offsetTop +','+ e.offsetWidth +','+ e.offsetHeight +' ('+ e.offsetParent +')');
    logit ('scrollLeft, Top, Width, Height: '+ e.scrollLeft +','+ e.scrollTop +','+ e.scrollWidth +','+ e.scrollHeight);
  }

  function dispEvent (msg, me)
  {
    logit (msg + ' Button:'+ me.button +' Screen:'+ me.screenX +','+ me.screenY +' client:'+  me.clientX +','+ me.clientY +' rTarget: '+ me.relatedTarget);
  }
}

function inspect(obj, maxLevels, level, doFunctions){
  var str = '', type, msg;
  if(level == null)  level = 0;
  if(maxLevels == null) maxLevels = 1;
  if(maxLevels < 1)
      return 'Inspect Error: Levels number must be > 0';
  if(obj == null)
    return 'ERROR: Object is NULL\n';
  var indent = '';
  for (var i=0; i<level; i++)
    indent += '  ';
  for(property in obj) {
    try {
        type =  matTypeof(obj[property]);
        if (doFunctions==true && (type == 'function')){
          str += indent + '(' + type + ') ' + property + "[FUNCTION]\n";
        } else if (type != 'function') {
          str += indent + '(' + type + ') ' + property + ( (obj[property]==null)?(': null'):('')) +' = '+ obj[property] +"\n";
        }
        if((type=='object' || type=='array') && (obj[property] != null) && (level+1 < maxLevels))
          str += inspect(obj[property], maxLevels, level+1, doFunctions);  // recurse
    }
    catch(err) {
      // Is there some properties in obj we can't access? Print it red.
      if(typeof(err) == 'string') msg = err;
      else if(err.message)        msg = err.message;
      else if(err.description)    msg = err.description;
      else                        msg = 'Unknown';
      str += '(Error) ' + property + ': ' + msg +"\n";
    }
  }
  str += "\n";
  return str;
}

// Array.prototype.compare = function(testArr) {
    // if (this.length != testArr.length) return false;
    // for (var i = 0; i < testArr.length; i++) {
        // if (this[i].compare) {
            // if (!this[i].compare(testArr[i])) return false;
        // }
        // if (this[i] !== testArr[i]) return false;
    // }
    // return true;
// }
String.prototype.StripQuotes = function() {
  return this.replace(/"/g,'');
}

String.prototype.entityTrans = { '&':'&amp;', '<':'&lt;',  '>':'&gt;',  '\"':'&quot;', '\'':'&#039', '<':'\\u003c', '/':'\\/', '\\':'\\\\', '\"':'\\\"','{':'&#123;','}':'&#125;'};
String.prototype.htmlSpecialChars = function() {
  var ret = this.toString();
  for (k in this.entityTrans)
     ret  = ret.split(k).join(this.entityTrans[k]);
  return ret;
}
String.prototype.htmlSpecialCharsDecode = function() {
  var ret = this.toString();
  for (k in this.entityTrans)
     ret = ret.split(this.entityTrans[k]).join(k);
  return ret;
}
String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
String.prototype.escape_space = function(){
  var s = this.split(" ");
  for(var i=0; i<s.length; i++)
    s[i] = escape(s[i]);
  //return s.join(" ");
  return this.replace(/</ig,"&#60;");
}
String.prototype.unescape_space = function(){
  var s = this.split(" ");
  for(var i=0; i<s.length; i++)
    s[i] = unescape(s[i]);
  //return s.join(" ");
  return this;
}

function officerId2String (oid){
  if (oid==null)
    return '';
  else if (oid==3)
    return 'Officer';
  else if (oid==2)
    return 'Vice Chance';
  else if (oid==1)
    return 'Chancellor';
  return '';
}

function enableCheck(value) {
  var output = false;
  
  if(value == Options.AllianceId) {
    output = true;
  }
  
  return output;
}

function getResourceProduction (cityId){
  var ret = [0,0,0,0,0];
  var now = unixTime ();
  
  var wilds = [0, 0, 0, 0, 0];
  var w = Seed.wilderness["city" + cityId];
  for (var k in w){
    var type = parseInt(w[k].tileType);
    if (type==10 || type==11)
      wilds[1] += parseInt(w[k].tileLevel);
    else
      wilds[type/10] += parseInt(w[k].tileLevel);
  }  
  
  knight = 0;       
  var s = Seed.knights["city" + cityId];
  if (s) {
    s = s["knt" + Seed.leaders["city" + cityId].resourcefulnessKnightId];
    if (s){
      var knight = parseInt(s.resourcefulness);
      if (s.resourcefulnessBoostExpireUnixtime > now)
        knight *= 1.25;
    }
  }
  var workerFactor = 1;
  var c = parseInt(Seed.citystats["city" + cityId]["pop"][0]);  // Current  population
  var w = parseInt(Seed.citystats["city" + cityId]["pop"][3]);  // Labor force
  if (w > c)
    workerFactor = c / w;
  
  for (var i=1; i<5; i++){
    var usage = Seed.resources["city" + cityId]["rec" + i];
    var items = 0;
    if (parseInt(Seed.playerEffects["r" + i + "BstExp"]) > now) {
      items = 0.25;
    }
    var tech = Seed.tech["tch" + i];
    ret[i] = parseInt((usage[2] * (1 + tech/10 + knight/100 + items + 0.05 * wilds[i]) * workerFactor + 100));
  }
  return ret;  
}

function objectName (o){
  var s = o.toString();
  return s.substr(7,s.length-8);
}

function matTypeof (v){
  if (typeof (v) == 'object'){
    if (!v)
      return 'null';
//    else if (unsafeWindow.Object.prototype.toString.apply(v) === '[object Array]')
    else if (v.constructor.toString().indexOf("Array")>=0 && typeof(v.splice)=='function')
      return 'array';
    else return 'object';
  }
  return typeof (v);
}

function updatebotbutton(text, id)
{
  var but=document.getElementById(id);
  but.innerHTML = '<span style="color: #ff6">'+text+'</span>';
}
    


function tbodyScroller (tbody, maxHeight){  
  tbody.style.maxHeight = '';
  tbody.style.height = '';
  tbody.style.overflowX = 'hidden';
  if (parseInt(tbody.clientHeight) > maxHeight){
    tbody.style.height = maxHeight + 'px';
    tbody.style.maxHeight = maxHeight + 'px';
    tbody.style.overflowY = 'auto';
  }
}
function getRemainingHeight (e, cont){
  var ec = getClientCoords(e);
  var cc = getClientCoords(cont);
  return cont.clientHeight - (ec.y - cc.y);
}


function addCommasInt(n){
  nStr = parseInt(n) + '';
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(nStr)) {
    nStr = nStr.replace(rgx, '$1' + ',' + '$2');
  }
  return nStr;
}

function addCommas(nStr){
  nStr += '';
  x = nStr.split('.');
  x1 = x[0];
  x2 = x.length > 1 ? '.' + x[1] : '';
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(x1)) {
    x1 = x1.replace(rgx, '$1' + ',' + '$2');
  }
  return x1 + x2;
}

function unixTime (){
  return parseInt (new Date().getTime() / 1000) + unsafeWindow.g_timeoff;
}
function htmlOptions (a, curVal){
  m = '';
  for (k in a)
    m += '<OPTION value="'+ k +'"'+ (k==curVal?' SELECTED':'')  +'>'+ a[k] +'</option>';
  return m;
}
function getFunctionName (func){
  var name=/\W*function\s+([\w\$]+)\(/.exec(func);
  if (!name)
    return '';
  return name[1];
}

function findAllBetween (txt, find1, find2){
  var m = [];
  var last = 0;
  while ( (i1=txt.indexOf(find1, last))>=0 && (i2=txt.indexOf (find2, i1))>=0 ) {
    m.push (txt.substring(i1+find1.length, i2));
    last = i2 + find2.length;
  }
  return m;
}

function strUpTo (s, find){
  var i = s.indexOf(find);
  if (i > 0)
    return s.substr(0, i);
  return s;
}

/********
 Xd Xh
 Xh Xm
 Xm Xs
 Xs
********/
function timestrShort(time) {
  time = parseInt (time);
  if (time > 86400){
    var m = [];
    time /= 3600;
    m.push (parseInt(time/24));
    m.push ('d ');
    m.push (parseInt(time%24));
    m.push ('h ');
    return m.join ('');    
  } else
    return timestr (time);
}

/**********************
 part       full
 Xd Xh Xm   Xd Xh Xm Xs
 Xh Xm      Xh Xm Xs
 Xm Xs      Xm Xs
 Xs         Xs
**********************/
function timestr(time, full) {
  time = parseInt (time);
  var m = [];
  var t = time;
  if (t < 61)
    return  t + 's';
  if (t > 86400){
    m.push (parseInt(t/86400));
    m.push ('d ');
    t %= 86400;
  }  
  if (t>3600 || time>3600){
    m.push (parseInt(t/3600));
    m.push ('h ');
    t %= 3600;
  }  
  m.push (parseInt(t/60));
  m.push ('m');
  if (full || time<=3600 ){
    m.push (' ');
    m.push (t%60);
    m.push ('s');  
  }
  return m.join ('');
}

/************  LIB singletons .... **************/
// TODO: fix REopening window
var WINLOG_MAX_ENTRIES = 1000;     // TODO
var WinLog = {
  state : null,
  win: null,
  eOut : null,
  lastE : null,
  enabled : true,
  reverse : true,
  busy : false,
  isOpening : false,

  open : function (){
    var t = WinLog;

    function eventButClear(){
      var t = WinLog;
      t.lastE = null;
      t.eOut.innerHTML ='';
    }
    
    function eventButReverse(){
      var t = WinLog;
      if (t.busy)
        return;
      t.busy = true;
      if (t.reverse){
        t.win.document.getElementById('wlRev').value= 'Top';
        t.reverse = false;
      } else{
        t.win.document.getElementById('wlRev').value= 'Bottom';
        t.reverse = true;
      }
      var n = t.eOut.childNodes.length;
      if (n < 2)
        return;
      for (i=n-2; i>=0; i--){
        t.eOut.appendChild (t.eOut.childNodes[i]);
      }
      t.busy = false;
    }
    
    if (!t.win || t.win.closed){
      t.isOpening = true;  
      // Firefox bug??? It appears as if a new thread is started on open, withOUT reusing same window? huh?
      t.win = window.open('', 'uwtrace', 'top=30,left=0,width=900,height=700,scrollbars=no,location=no,menubar=no,directories=no,status=no');
      t.isOpening = false;
      t.state = null;
    }
    
    if (t.state == null){
      t.win.document.body.innerHTML = '<STYLE>pre{margin:0px} hr{margin:3px; height:1px; border:0px; color:#cee; background-color:#cee}</style>\
        <BODY style="margin:0px; padding:0px; border:none">\
        <DIV id=winlogtop style="background-color:#d0d0d0; margin:0px; padding:0px; border:1px solid">\
        <INPUT id=wlClear type=submit value="Clear"> &nbsp; <INPUT id=wlRev type=submit value="Bottom"></div>\
        <DIV id=wlOut style="overflow-y:auto; height:100%; max-height:100%"></div></body>';
      t.win.document.getElementById('wlClear').addEventListener('click', eventButClear, false);
      t.win.document.getElementById('wlRev').addEventListener('click', eventButReverse, false);
      t.eOut =  t.win.document.getElementById('wlOut');
      t.lastE = null;
      t.state = 1;
    }
  },

  writeText : function (msg){
    var t = WinLog;
    if (!t.enabled || t.isOpening)
      return;
    t.write (msg.htmlSpecialChars());
  },
  
  write : function (msg){
    var t = WinLog;
    if (!t.enabled || t.isOpening)
      return;
    t.open();
    var te = document.createElement('pre');
    var now = new Date();
    var m = [];
    var millis = now.getMilliseconds();
    m.push (now.toTimeString().substring (0,8));
    m.push ('.');
    if (millis<100)
      m.push('0');
    if (millis<10)
      m.push('0');
    m.push(millis);
    m.push (': ');
    m.push (msg);
    te.innerHTML = m.join('');
    if (t.reverse){
      if (t.lastE == null){
        t.eOut.appendChild(te);
        t.lastE = te;
      } else {
        t.eOut.insertBefore(te, t.lastE);
      }

      var hr = document.createElement('hr');
      t.eOut.insertBefore(hr, te);
      t.lastE = hr;
    } else {
      t.eOut.appendChild(te);
      t.eOut.appendChild(document.createElement('hr'));
    }
  },

};

    
/*********************************** Gifts TAB ***********************************/
function explodeUrlArgs (url){
  var i = url.indexOf ('?');
  var a = url.substr(i+1).split ('&');
  var args = {};

  for (i=0; i<a.length; i++){
    var s = a[i].split ('=');
    args[s[0]] = s[1];
  }

  return args;
}

// returns: page text or null on comm error
function GM_AjaxPost (url, args, notify, label) {
  if (ENABLE_GM_AJAX_TRACE) {
    WinLog.writeText ('GM_AjaxPost ('+ label +'): ' + url +'\n'+ inspect (args, 5, 1));
  }
  
  GM_xmlhttpRequest({
    method: "post",
    url: url,
    data: implodeUrlArgs(args),
    headers: { "Content-Type": "application/x-www-form-urlencoded", 'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': '1.6.1',
               'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' },

    onload: function (rslt) {
      if (ENABLE_GM_AJAX_TRACE) WinLog.writeText ( 'GM_AjaxPost.onLoad ('+ label +'):\n '  + inspect (rslt, 6, 1));  
      notify (rslt.responseText);
    },

    onerror: function () {
      notify (null);
    },
  });
}

// returns: page text or null on comm error
function GM_AjaxGet (url, args, notify, label){
  if (ENABLE_GM_AJAX_TRACE) {
    WinLog.writeText ('GM_AjaxGet ('+ label +'): ' + url);
  }
  
  GM_xmlhttpRequest({
    method: "get",
    url: addUrlArgs(url, args),

    onload: function (rslt) {
      if (ENABLE_GM_AJAX_TRACE) WinLog.writeText ( 'GM_AjaxGet.onLoad ('+ label +')  len='+ rslt.responseText.length +':\n '  + inspect (rslt, 6, 1));  
      notify (rslt.responseText);
    },

    onerror: function () {
      notify (null);
    },
  });
}         
  
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Gifts
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Gifts = {
  tabOrder : 60,
  gifts : null,
  myDiv : null,
  doList : [], // list of gifts to accept
  doServer : 0,
  accepting : false,
    
  init : function (div){
    var t = Tabs.Gifts;
    t.myDiv = div;    
    div.innerHTML = '<TABLE cellpadding=0 cellspacing=0 class=pbTab width=100%><TR><TD width=10 align=left><a href=https://apps.facebook.com/kingdomsofcamelot/?page=choosegift title="SendGifts" target="_blank">SendGifts</a></td><TD width=200></td><TD align=center><INPUT id="pasubGifts" type=submit value="Check for Gifts" \></td><TD width=200 align=right><INPUT id=paGiftHelp type=submit value=HELP></td></tr></table><HR>\
        <DIV id=giftDiv style="width:100%; min-height:300px; height:100%">';
    document.getElementById('pasubGifts').addEventListener ('click', t.e_clickedGifts, false);
    document.getElementById('paGiftHelp').addEventListener ('click', t.helpPop, false);
    if (!Options.giftDomains.valid)
      Options.giftDomains.list[getServerId()] = unsafeWindow.domainName;
  },
  
  show : function (){
  },
  hide : function (){
  },
  
  helpPop : function (){
    var helpText = '<BR>The GIFTS tab helps you accept gifts easier than going through facebook. To use it, first hit the \'Check for Gifts\'\
        button.  This will fetch the facebook gifts page and will list all of the KofC gifts which are available.<BR><BR>\
        From the list, check all of the gifts that you want to accept or press the \'All\' button to select all of them.  Be sure to select which \
        domain you wish to apply the gifts to. If you want the gifts to be deleted from facebook after accepting them, set the \'delete gifts\'\
        option to \'Always\'. Now, press the \'Accept Gifts\' button to accept the selected gifts.  Note that this process takes some time as there are 4 webpages\
        that are being accessed for each gift!<BR><BR>\
        NOTES:<UL><LI>The Facebook gifts page lists up to 100 gifts for <B>all</b> of your game apps. This means that only some of the KofC\
        gifts which are available will be listed. After accepting gifts, be sure to \'Check for Gifts\' again to see if more show up!<p>\
        <LI>If you choose not to delete gifts after accepting them, they may be available to get again! After the process is complete, just press the\
        \'Check for Gifts\' button again to see what gifts are available.</ul>';
    var pop = new pbPopup ('giftHelp', 0, 0, 500, 340, true);
    pop.centerMe (mainPop.getMainDiv());  
    pop.getMainDiv().innerHTML = helpText;
    pop.getTopDiv().innerHTML = '<CENTER><B>Power Bot Help</b>: Accepting gifts</center>';
    pop.show (true);
  },
  
      
  e_clickedGifts : function  (){     // (also cancel accepting)
    var t = Tabs.Gifts;
    if (t.accepting){
      document.getElementById('pasubGifts').value = 'Check for Gifts';
      document.getElementById('giftDiv').innerHTML+= '<BR><SPAN class=boldRed>Cancelled.</span>';
      t.accepting = false;
      return;
    }
    document.getElementById('giftDiv').innerHTML = 'Fetching Facebook gifts page ...';
    
    t.fetchGiftsPage (gotGiftsPage);
    function gotGiftsPage(rslt){
      if (rslt.errMsg){
        document.getElementById('giftDiv').innerHTML += rslt.errMsg;
        return;
      }
      t.gifts = rslt;
      if (!Options.giftDomains.valid && t.gifts.length>0){
        t.ajaxGetGiftData (t.gifts[0], listGifts, function (){});    // try to get domain list ... don't delete gift!
        return;
      }
      listGifts();
    }
    
    function listGifts (){
      var m = '<DIV class=pbStat><CENTER>KofC gifts &nbsp; &nbsp; &nbsp; ('+ t.gifts.length +' found)</center></div>';

      if (t.gifts.length<1){
        document.getElementById('giftDiv').innerHTML = m + '<BR><BR><CENTER>No gifts found!</center>';
        return;
      }

      m += '<TABLE class=pbTab align=center><TR><TD align=right>Server to apply gifts to: </td><TD>'
        + htmlSelector (Options.giftDomains.list, getServerId(), 'id=pbGiftServers') +'</td></tr>\
          <TR><TD align=right>Delete gifts after accepting</td><TD>'
        + htmlSelector ({y:'Always', e:'Only if Error', n:'Never'}, Options.giftDelete, 'id=pbGiftDel')
        + '</td></tr><TR><TD>Select gifts you want to accept and hit: </td><TD width=250><INPUT type=submit id=pbGiftDo value="Accept Gifts">\
        &nbsp; <SPAN id=pbGiftNone class=boldRed></span></td></tr></table><HR><TABLE class=pbTab><TR valign=top><TD>\
        <INPUT id=pbGiftButAll type=submit value="All" style="width:100%; margin-bottom:5px"><BR><INPUT id=pbGiftButNone type=submit value="None"></td>\
        <TD width=10></td><TD><TABLE align=center cellpadding=0 cellspacing=0 class=pbTabLined>\
        <TBODY id=pbGiftTbody style="height:250px; overflow:auto; display:block;">\
        <TR style="font-weight:bold; background:white"><TD>Gift</td><TD>Date</td><TD>From (server)</td><TD width=20></td></tr>';
      t.gifts.sort (function (a,b){  // sort by gift name, date
        var x = a.gift.localeCompare (b.gift);
        if (x != 0)
          return x;
        return a.args.da.localeCompare(b.args.da);
      });

      for (var i=0; i<t.gifts.length; i++){
        var giftName = t.gifts[i].gift;
        if (t.gifts[i].args.si == 9)
          giftName += ' (Daily)';
        var date = t.gifts[i].args.da.substr(0,4) +'-'+ t.gifts[i].args.da.substr(4,2) +'-'+ t.gifts[i].args.da.substr(6,2);
        m += '<TR><TD><INPUT type=checkbox id=pbgchk_'+ i +'> &nbsp;'+ giftName +'</td><TD>'+ date +'</td>\
              <TD>'+ t.gifts[i].giver +' ('+ t.gifts[i].args.exs +')</td></tr>';
      }

      document.getElementById('giftDiv').innerHTML = m + '</tbody></table></td></tr></table>';
      document.getElementById('pbGiftDo').addEventListener ('click', t.getErDone, false);
      document.getElementById('pbGiftButAll').addEventListener ('click', t.e_butAll, false);
      document.getElementById('pbGiftButNone').addEventListener ('click', t.e_butNone, false);
      // var tbody = document.getElementById('pbGiftTbody');
      // tbodyScroller (tbody, getRemainingHeight (tbody, mainPop.div));
    }
  },

  e_butAll : function (){
    var t = Tabs.Gifts;
    for (var i=0; i<t.gifts.length; i++) {
      document.getElementById('pbgchk_'+i).checked = true;
    }
  },
  
  e_butNone : function (){
    var t = Tabs.Gifts;

    for (var i=0; i<t.gifts.length; i++) {
      document.getElementById('pbgchk_'+i).checked = false;
    }
  },
  
  getErDone : function (){
    var t = Tabs.Gifts;
    t.doList = [];
    document.getElementById('pbGiftNone').innerHTML = '';
    Options.giftDelete = document.getElementById('pbGiftDel').value;

    for (var i=0; i<t.gifts.length; i++){
      if (document.getElementById('pbgchk_'+i).checked) {
        t.doList.push (t.gifts[i]);
      }
    }
    
    if (t.doList.length==0){
      document.getElementById('pbGiftNone').innerHTML = 'None Selected!';
      return;
    }
    
    t.doServer = document.getElementById('pbGiftServers').value;
    t.accepting = true;
    document.getElementById('pasubGifts').value = 'Stop Accepting';
    document.getElementById('giftDiv').innerHTML = '<DIV id=acpDiv style="height:400px; max-height:400px; overflow-y:auto"><B>Accepting '+ t.doList.length +' gifts:</b><BR></div>';    
    t.acceptNext ();
  },
    
  allDone : function (msg){
    var t = Tabs.Gifts;
    document.getElementById('acpDiv').innerHTML += '<BR><BR>' + msg;
    document.getElementById('pasubGifts').value = 'Check for Gifts';
    t.accepting = false;
  },
    
  acceptNext : function (){
    var t = Tabs.Gifts;
    var gift = t.doList.shift();
    if (gift == null){
      t.allDone ('Done accepting gifts.');
      return;
    }
    var acpDiv = document.getElementById('acpDiv');
    var curDiv = document.createElement ('div');
    acpDiv.appendChild (curDiv);
    curDiv.innerHTML = '<B>'+ gift.gift +'</b> from '+ gift.giver +' on '+ gift.args.da.substr(0,4) +'-'+ gift.args.da.substr(4,2) +'-'+ gift.args.da.substr(6,2) +': ';    
    var statSpan = document.createElement ('span');
    curDiv.appendChild (statSpan);
    statSpan.innerHTML = 'Getting data ';
    t.ajaxGetGiftData (gift, gotGiftData, progress);
    
    function progress (m){
      if (t.accepting)
        statSpan.innerHTML += ' '+m;
    }
        
    function gotGiftData (rslt){
      if (!t.accepting)
        return;
      if (rslt.ok){
        statSpan.innerHTML += ' &nbsp; Accepting .';
        t.ajaxAcceptGift (gift, t.doServer, doneAccepting);
        return;
      }
        
      if (rslt.feedback) {
        msg = '<B>'+ rslt.feedback + '</b>';
      } else {
        msg = '<SPAN class=boldRed>ERROR: '+ rslt.ajaxErr +'</span>';
      }

      if (rslt.del && Options.giftDelete!='n'){
        t.deleteGift (gift);  
        msg += ' Gift Deleted.';
      }
      
      curDiv.removeChild (statSpan);
      curDiv = document.createElement ('div');
      curDiv.className = 'indent25';
      acpDiv.appendChild (curDiv);
      curDiv.innerHTML = msg;
      t.acceptNext ();  
    }
    
    function doneAccepting (rslt){
      if (!t.accepting)
        return;
      var msg = 'OK.';
      if (rslt.ok)
        actionLog ('Accepted Gift:  '+ gift.gift +' from '+ gift.giver +' on '+ gift.args.da.substr(0,4) +'-'+ gift.args.da.substr(4,2) +'-'+ gift.args.da.substr(6,2)     );
      else
        msg = '<SPAN class=boldRed>'+ rslt.msg +'</span>';
      statSpan.innerHTML = msg;
      if (Options.giftDelete=='y'){
        statSpan.innerHTML += ' &nbsp; Deleted.';
        t.deleteGift (gift);      
      }
      t.acceptNext ();  
    }
  },

  ajaxAcceptGift : function (gift, serverId, notify){
    var url;
    var pargs = {};
        
    if (gift.dat.ver == 1){
      url = gift.dat.url;
      pargs.giftId = gift.dat.giftId;
      pargs.hasExistingServer = 1;
      pargs.serverid = serverId;
      pargs.go = 'Next';
      GM_AjaxPost (url, pargs, ver1GotPost, 'Accept');
    } else {
      var i = gift.dat.url.indexOf('src/');
      
      url = gift.dat.url.substr(0,i) +'src/ajax/claimgift.php?wcfbuid='+ gift.dat.wcfbuid;        
      pargs = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
      pargs.fb_sig_ext_perms = unescape(pargs.fb_sig_ext_perms);
      pargs.ver = '2';
      pargs.selectedS = serverId;
      pargs.giftinviteid = gift.dat.giftId;
      GM_AjaxPost (url, pargs, ver2GotPost, 'Accept');
    }
     
    //  parse multiple reply formats .....         
    function ver1GotPost (rslt){
      if (rslt == null){
        notify ({ok:false, msg:"AJAX Error"});
        return;
      }
      var m = /<div class=\'nm\'>(.*?)<\/div/im.exec(rslt);
      if (m)
        notify ({ok:false, msg: 'Got '+ m[1]});
      else
        notify ({ok:true, msg:'OK'});
    }
    
    function ver2GotPost (rslt){
      if (rslt == null){
        notify ({ok:false, msg:"AJAX Error"});
        return;
      }
      rslt = eval ('('+ rslt +')');
      if (rslt.ok)
        rslt.msg = 'OK';
      notify (rslt);
    }
  },

      
  deleteGift : function (gift){
    var pargs = {};

    for (var i=0; i<gift.inputs.length; i++){
      pargs[gift.inputs[i].name] = gift.inputs[i].value;
    }

    GM_AjaxPost (window.location.protocol+'//www.facebook.com/ajax/reqs.php?__a=1', pargs, gotAjaxPost, 'Delete');

    function gotAjaxPost (p){
    }
  },

    
  // get 3 pages ... facebook convert page, facebook claim page and first KofC page (for gift ID) ...
  // adds: dat.url, dat.giftId and dat.ver to gift object (if available)
  // notify: {ok:true/false,  feedback:,  ajaxErr:  }    
  ajaxGetGiftData : function (gift, notify, progress, DELETE){
    var t = Tabs.Gifts;
    gift.dat = {};
    GM_AjaxGet (gift.submit, null, got1, 'Page 1');        
        
    function got1 (page){
      // sample URL: http://apps.facebook.com/kingdomsofcamelot/?page=claimdailygift&gid=361&sid=4411654&s=88&in=4411654&si=9      
      // sample result: .... window.location.replace("http:\/\/apps.facebook.com\/kingdomsofcamelot\/?page=claimgift&gid=1045&sid=1432568&s=250&in=1432568&si=5"); ...
      if (page == null)
        notify ({ajaxErr:'COMM Error - page 1'});
      progress ('1');
      page = page.htmlSpecialCharsDecode();
      var m = page.match (/form action="(.*?)"/im);

      if (m == null) {
        notify ({ajaxErr:'PARSE Error - page 1'});
      }
      
      var url = m[1].htmlSpecialCharsDecode(); 
      url = unescape(url);
      url = url.replace ('\\/', '/', 'g');
      url = url.replace (/\\u00253A/g, ':');
      url = url.replace (/\\u00257C/g, '|');
      var signed_request = /signed_request" value="(.*?)"/im.exec (page);
      var opts = [];
      opts.signed_request = signed_request[1];

      GM_AjaxPost (url, opts, got2, 'Page 2');        
    }
  
    function got2 (page){
      if (page == null)
        notify ({ajaxErr:'COMM Error - page 2'});
      progress ('2');

      var m = /top.location.href = \"(.*?)\"/im.exec (page);

      if (m == null)
        m = /top.location.replace\(\"(.*?)\"\)/im.exec (page);
      if (m == null)
        notify ({ajaxErr:'PARSE Error - page 2'});
      var url = m[1].htmlSpecialCharsDecode(); 
      GM_AjaxGet (url, '', got3, 'Page 3');        
    }
    
    // sample URL: http://www88.kingdomsofcamelot.com/fb/e2/src/claimDailyGift_src.php?sid=4411654&gid=361&standalone=0&res=1&iframe=1&wcfbuid=1400526627&fbml_sessionkey=2.wdwjP4blBLkO2wXAFqDglg__.3600.1293681600-1400526627&lang=en&in=4411654&si=9&ts=1293677199.881&page=claimdailygift&gid=361&sid=4411654&s=88&in=4411654&si=9&appBar=&kabamuid=114014&tpuid=alYJXw-Us9z9qjRn3DHChEtsFvo&fb_sig_in_iframe=1&fb_sig_base_domain=kingdomsofcamelot.com&fb_sig_locale=en_GB&fb_sig_in_new_facebook=1&fb_sig_time=1293677199.924&fb_sig_added=1&fb_sig_profile_update_time=1267240352&fb_sig_expires=1293681600&fb_sig_user=1400526627&fb_sig_session_key=2.wdwjP4blBLkO2wXAFqDglg__.3600.1293681600-1400526627&fb_sig_ss=7wEsU_e0FLqhrGxE1LAZDg__&fb_sig_cookie_sig=514b59deb303becb5c5c654c9d457732&fb_sig_ext_perms=email%2Cuser_birthday%2Cuser_religion_politics%2Cuser_relationships%2Cuser_relationship_details%2Cuser_hometown%2Cuser_location%2Cuser_likes%2Cuser_activities%2Cuser_interests%2Cuser_education_history%2Cuser_work_history%2Cuser_online_presence%2Cuser_website%2Cuser_groups%2Cuser_events%2Cuser_photos%2Cuser_videos%2Cuser_photo_video_tags%2Cuser_notes%2Cuser_about_me%2Cuser_status%2Cfriends_birthday%2Cfriends_religion_politics%2Cfriends_relationships%2Cfriends_relationship_details%2Cfriends_hometown%2Cfriends_location%2Cfriends_likes%2Cfriends_activities%2Cfriends_interests%2Cfriends_education_history%2Cfriends_work_history%2Cfriends_online_presence%2Cfriends_website%2Cfriends_groups%2Cfriends_events%2Cfriends_photos%2Cfriends_videos%2Cfriends_photo_video_tags%2Cfriends_notes%2Cfriends_about_me%2Cfriends_status&fb_sig_country=us&fb_sig_api_key=0ab5e11ff842ddbdbf51ed7938650b3f&fb_sig_app_id=130402594779&fb_sig=fca33813d9e1c9d411f0ddd04cf5d014
    function got3 (page){
      if (page == null)
        notify ({ajaxErr:'COMM Error - page 3'});
      progress ('3');
      page = page.htmlSpecialCharsDecode();
      var m = page.match (/form action="(.*?)"/im);
      if (m == null)
        notify ({ajaxErr:'PARSE Error - page 3'});
      var url = m[1].htmlSpecialCharsDecode();
      url = unescape(url);
      url = url.replace ('\\/', '/', 'g');
      var signed_request = /signed_request" value="(.*?)"/im.exec (page);
      var opts = [];
      opts.signed_request = signed_request[1];
      GM_AjaxPost (url, opts, got4, 'Page 4');        
    }
  
  function got4 (page){
      if (page == null)
        notify ({ajaxErr:'COMM Error - page 4'});
      progress ('4');
      page = page.htmlSpecialCharsDecode();
    
      var m = page.match (/src='(.*?)'/im);
      if (m == null)
        m = page.match (/form action="(.*?)"/im);
      if (m == null)
        notify ({ajaxErr:'PARSE Error - page 4'});
      var url = m[1].htmlSpecialCharsDecode();
      url = url.replace (/lang=.*?&/, 'lang=en&');  
      url = url.replace ('\\/', '/', 'g');  
      url = url.replace ('&amp;', '&', 'g');
      url = url.replace ('" + (new Date()).getTime() + "', (new Date()).getTime());
      gift.dat.url = url;
      var signed_request = /signed_request" value="(.*?)"/im.exec (page);
      var opts = [];
      opts.signed_request = signed_request[1];
      GM_AjaxPost (url, opts, got5, 'Page 5');        
    }
    
    function got5 (page){
      if (page == null)
        notify ({ajaxErr:'COMM Error - page 5'});
      progress ('5');
      page = page.htmlSpecialCharsDecode();
      var m = /<div class=\'giftreturned\'>(.*?)<\/div/im.exec(page);
      if (m != null){
        notify ({feedback:m[1], del:true});
        return;
      }
      var m = /(We were unable to find your gift.*?)</im.exec(page);
      if (m != null){
        notify ({feedback:m[1], del:true});
        return;
      }
      var m = /(Unable to get the list of your friends.*?)</im.exec(page);
      if (m != null){
        notify ({feedback:m[1]});
        return;
      }
      var m = /(Facebook says you are not friends.*?)</im.exec(page);
      if (m != null){
        notify ({feedback:m[1], del:true});
        return;
      }
            
      var regexp = /<option value='(.*?)'.*?>(.*?)</img ;
      var m;
      while ( (m = regexp.exec (page)) != null){
        if (m[1] != 'noserver')
          Options.giftDomains.list[m[1]] = m[2];  
      }
      Options.giftDomains.valid = true;
      if (page.indexOf('ver:2') >= 0){
        m = /giftinviteid:(.*?),/im.exec(page);
        if (m == null)
          notify ({ajaxErr:'PARSE Error (ver:2, giftinviteid not found) - page 5'});
        gift.dat.giftId = m[1];
        gift.dat.ver = 2;
        /** for KofC change 20110119
        m = /wcfbuid=([0-9]*)/im.exec(page);
        if (m == null){
          notify ({ajaxErr:'PARSE Error (ver:2, wcfbuid not found) - page 5'});
          return;
        }
        gift.dat.wcfbuid = m[1];
        **/        
      } else {
        m = /name='giftId' value='(.*?)'/im.exec(page);
        if (m == null){
          notify ({ajaxErr:'PARSE Error (ver:1, giftId not found) - page 5'});
          return;
        }
        gift.dat.giftId = m[1];
        gift.dat.ver = 1;
      }
      notify ({ok:true});
    }
  },
  
  // notify with gifts[] or: {errMsg:xxx}
  fetchGiftsPage : function (notify){
  var gifts = [];
    GM_AjaxGet (window.location.protocol+'//www.facebook.com/games', '', parseGiftsPage, 'FB Gifts Page');
    
    // ...profile.php?id=100000710937192">Anestis Mallos</
    // Here is a GIFTNAME you can use
    // OR:  ... would like to give you a gift of GIFTNAME in Kingdoms of Camelot
    // OR:  ... would like to give you a GIFTNAME in Kingdoms of Camelot
    // <input value=\"Accept\" type=\"submit\" name=\"actions[http:\/\/apps.facebook.com\/kingdomsofcamelot\/convert.php?pl=1&in=4411654&ty=1&si=9&wccc=fcf-inv-9&ln=11&da=20101229&ex=gid%3A361%7Csid%3A4411654%7Cs%3A88]\" \/><\/label>
    function parseGiftsPage  (p){
      if (p == null)
        notify ({errMsg:'Ajax Comm Error'});
      p = p.htmlSpecialCharsDecode();
      var t = Tabs.Gifts;
      var gifts = [];
      try {    
        var m = p.split ('<form');  
        for (var i=0; i<m.length; i++){
          if ( m[i].indexOf('kingdomsofcamelot')<0)
            continue;
      var mm = m[i].match( /facebook.com\/.*\">(.*?)<\/a><\/span>.*?(?:would like to give you a (?:gift of|)(.*?) in |Here is a(.*?)you can use)/im );
      if (mm==null)
            mm = m[i].match( /facebook.com\/.*\">(.*?)<\/span><\/span><\/a>.*?(?:would like to give you a (?:gift of|)(.*?) in |Here is a(.*?)you can use)/im );
      if (mm==null)
             mm = m[i].match( /appRequestBodyNewA\">(.*) sent an you an invitation to use Kingdoms of Camelot/im );
          if (mm==null)
            continue;
          var giver = mm[1];
          if (mm[2])
            var gift = mm[2].trim();
            
          // get all inputs ...  (name, value, type)          
          var inps = [];
          var args = {};  
          var inpsub = null;            
          var ins = m[i].match (/<input.*?>/igm);
          for (var ii=0; ii<ins.length; ii++){
            var it = {};
            mm = /value=\"(.*?)\"/im.exec(ins[ii]);
      if (mm==null)
        continue;
            it.value = mm[1];
            mm = /name=\"(.*?)\"/im.exec(ins[ii]);
            if (mm==null)
        continue;
            it.name = mm[1];
            mm = /type=\"(.*?)\"/im.exec(ins[ii]);
            if (mm==null)
        continue;
            it.type = mm[1];
            if (it.type=='submit' && it.name!='actions[reject]'){
              it.name = eval ('"'+ it.name +'"');          
              mm = /actions\[(.*?)\]/im.exec(it.name);
              inpsub = mm[1].replace('\\/', '/', 'g');
              inpsub = inpsub.replace('&amp;', '&', 'g');
              var a = inpsub.split ('&');
              for (var iii=0; iii<a.length; iii++){
                var aa = a[iii].split ('=');
                if (aa[0]=='da' || aa[0]=='si'){
                  args[aa[0]] = unescape(aa[1]);
                } else if (aa[0] == 'ex') {
                  var s = unescape(aa[1]).split ('|');
                  for (var iiii=0; iiii<s.length; iiii++){
                    var ss = s[iiii].split(':');
                    if (ss[0] == 's')
                      args.exs = ss[1];
          else
            args[ss[0]] = ss[1];
                  }
                }
              }
        if(args.gid)
        gift = unsafeWindow.itemlist['i'+args.gid].name;
            } else {
              inps.push (it);
            }
          }
          if (args.da)
            gifts.push ({giver:giver, gift:gift, args:args, submit:inpsub, inputs:inps});
        }
        notify (gifts);
      } catch (e) {
        notify ({errMsg:"Error parsing Facebook gift page "+ e});
      }
    }
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Resources
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Resources = {
  tabOrder : 100,
  resource : {1:'Food', 2:'Wood', 3:'Stone', 4:'Ore'},
  users : [],
  myDiv : null,
  doList : [], // list of gifts to accept
  accepting : false,
  city : null,
  total : {gold:0, 1:0, 2:0, 3:0, 4:0},
    
  init : function (div){
    var t = Tabs.Resources;
    t.myDiv = div;
    div.innerHTML = '<TABLE cellpadding=0 cellspacing=0 class=pbTab width=100%><TR><TD align=center><INPUT id="pballlist" type=submit value="Fetch User List" \></td></tr></table><HR>\
        <DIV id=resDiv style="width:100%; min-height:300px; height:100%">';
    document.getElementById('pballlist').addEventListener ('click', t.e_clickfetchlist, false);

  },
  
  show : function (){
  },
  hide : function (){
  },
  
  progress : function (msg, span, add){
  if(add)
    document.getElementById(span).innerHTML+=msg;
  else
    document.getElementById(span).innerHTML=msg;
  },

  e_clickfetchlist : function  (){     // (also cancel accepting)
    var t = Tabs.Resources;
  t.users = [];
    if (t.accepting){
      document.getElementById('pballlist').value = 'Fetch User List';
      document.getElementById('resDiv').innerHTML+= '<BR><SPAN class=boldRed>Cancelled.</span>';
      t.accepting = false;
      return;
    }
    document.getElementById('resDiv').innerHTML = 'Fetching user list ... <span id=pbResUserListCount></span>';
    
    t.fetchUserList (gotUserList);
    function gotUserList(userList){
    if(userList.length < 1){
      listGifts();
      return;
    }
    document.getElementById('resDiv').innerHTML += '<BR>Check if able to collect ... <span id=pbResUserAvailCount></span>';
    t.checkDailyAction(userList, listGifts);
  }
    
    function listGifts (){
    t.city = Cities.cities[0];
    var m = '<DIV class=pbStat><CENTER>User List &nbsp; &nbsp; &nbsp; ('+ t.users.length +' found)</center></div>';
      if (t.users.length<1){
        document.getElementById('resDiv').innerHTML = m + '<BR><BR><CENTER>No users found!</center>';
        return;
      }
      m += '<TABLE class=pbTab align=center><TR><TD align=right>City to apply gifts to: </td><TD id=pbrescityselspan></td></tr>\
          <TR><TD align=right>Select resource to collect</td><TD>'
        + htmlSelector (t.resource, Options.getResType, 'id=pbResColType')
        + '</td></tr><TR><TD>Select users you want to collect from and hit: </td><TD width=250><INPUT type=submit id=pbResDo value="Accept Resources">\
        &nbsp; <SPAN id=pbResNone class=boldRed></span></td></tr></table><HR><TABLE class=pbTab><TR valign=top><TD>\
        <INPUT id=pbResButAll type=submit value="All" style="width:100%; margin-bottom:5px"><BR><INPUT id=pbResButNone type=submit value="None"></td>\
        <TD width=10></td><TD><TABLE align=center cellpadding=0 cellspacing=0 class=pbTabLined>\
        <TBODY id=pbResTbody style="height:250px; overflow:auto; display:block;">\
        <TR style="font-weight:bold; background:white"><TD>Name</td><TD>Might</td><TD width=20></td></tr>';
      for (var i=0; i<t.users.length; i++){
        m += '<TR><TD><INPUT type=checkbox id=pbrchk_'+ i +'> &nbsp;'+ t.users[i].name +'</td><TD>'+ t.users[i].might +'</td></tr>';
      }
      document.getElementById('resDiv').innerHTML = m + '</tbody></table></td></tr></table>';
    new CdispCityPicker ('pbrescitysel', document.getElementById('pbrescityselspan'), true, t.e_CityButton, t.city.idx);
      document.getElementById('pbResDo').addEventListener ('click', t.getErDone, false);
      document.getElementById('pbResButAll').addEventListener ('click', t.e_butAll, false);
      document.getElementById('pbResButNone').addEventListener ('click', t.e_butNone, false);
      // var tbody = document.getElementById('pbResTbody');
      // tbodyScroller (tbody, getRemainingHeight (tbody, mainPop.div));
    }
  },

  e_CityButton : function (city, x, y){
    var t = Tabs.Resources;
  t.city = city;
  },
  
  e_butAll : function (){
    var t = Tabs.Resources;
    for (var i=0; i<t.users.length; i++)
      document.getElementById('pbrchk_'+i).checked = true;
  },
  
  e_butNone : function (){
    var t = Tabs.Resources;
    for (var i=0; i<t.users.length; i++)
      document.getElementById('pbrchk_'+i).checked = false;
  },
  
  getErDone : function (){
    var t = Tabs.Resources;
    t.doList = [];
    document.getElementById('pbResNone').innerHTML = '';
  Options.getResType = document.getElementById('pbResColType').value;
  t.total = {gold:0, 1:0, 2:0, 3:0, 4:0};
    for (var i=0; i<t.users.length; i++){
      if (document.getElementById('pbrchk_'+i).checked)
        t.doList.push (t.users[i]);
    }
    if (t.doList.length==0){
      document.getElementById('pbResNone').innerHTML = 'None Selected!';
      return;
    }
    t.accepting = true;
    document.getElementById('pballlist').value = 'Stop Accepting';
    document.getElementById('resDiv').innerHTML = '<DIV id=rsltDiv style="height:400px; max-height:400px; overflow-y:auto"><B>Accepting from '+ t.doList.length +' users:</b><BR></div>';    
    t.acceptNext ();
  },

    
  allDone : function (msg){
    var t = Tabs.Resources;
  msg += '<BR><BR> Total resources gained : <BR>\
       Gold: '+addCommas(t.total.gold)+'<BR>';
  for(var i=1; i<=4; i++){
    msg += t.resource[i]+': '+addCommas(t.total[i])+'<BR>';
  }
    document.getElementById('rsltDiv').innerHTML += '<BR><BR>' + msg;
    document.getElementById('pballlist').value = 'Fetch User List';
    t.accepting = false;
  },
  
    
  acceptNext : function (){
    var t = Tabs.Resources;
    var gift = t.doList.shift();
    if (gift == null){
      t.allDone ('Done accepting resources.');
      return;
    }
    var acpDiv = document.getElementById('rsltDiv');
    var curDiv = document.createElement ('div');
    acpDiv.appendChild (curDiv);
    curDiv.innerHTML = '<B>From '+ gift.name +': ';    
    var statSpan = document.createElement ('span');
    curDiv.appendChild (statSpan);
    statSpan.innerHTML = 'Accepting... ';
    t.getCourtAction (gift, gotGiftData);
        
    function gotGiftData (rslt)
    {
//logit ("getErDone.gotGiftData ... \n"+ inspect (gift, 8, 1));
      if (!t.accepting)
        return;
      
      if (rslt.ok)
      {
        var msg = rslt.gold +' gold and '+rslt.resource +' '+ t.resource[rslt.resourcetype]+'&nbsp; &nbsp; OK.';
        actionLog ('Accepted from '+gift.name+': '+ rslt.gold +' gold and '+ rslt.resource +' '+ t.resource[rslt.resourcetype]);
        statSpan.innerHTML += msg;
        t.total.gold += rslt.gold;
        t.total[rslt.resourcetype] += rslt.resource;
        t.acceptNext ();  
        return;
      }
        
      if (rslt.msg)
        msg = '<B>'+ rslt.msg + '</b>';
      else
        msg = '<SPAN class=boldRed>ERROR: '+ rslt.ajaxErr +'</span>';

      curDiv.removeChild (statSpan);
      curDiv = document.createElement ('div');
      curDiv.className = 'indent25';
      acpDiv.appendChild (curDiv);
      curDiv.innerHTML = msg;
      t.acceptNext ();  
    }
  },

  getMembersInfo : function (pageNo, notify) 
  {
    var t = Tabs.Resources;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    params.pageNo = pageNo;
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/allianceGetMembersInfo.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (rslt) 
      {
        notify (rslt);
      },
      
      onFailure: function (rslt) 
      {
        notify ({errMsg:'Ajax Comm Error'});
      },
    });
  },
  
  getDailyAction : function (uid, notify)
  {
    var t = Tabs.Resources;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    params.pid = uid;
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/viewCourt.php" + unsafeWindow.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      onSuccess: function (rslt) {
        notify (rslt);
      },
      onFailure: function (rslt) {
        notify ({errMsg:'Ajax Comm Error'});
      },
    });
  },
  
  getCourtAction : function (gift, notify)
  {
    var t = Tabs.Resources;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    params.atype = Options.getResType;
    params.toid = gift.userId;
    params.givercityid = t.city.id;
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/courtDoAction.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (rslt) 
      {
        notify (rslt);
      },
      
      onFailure: function (rslt) 
      {
        notify ({errMsg:'Ajax Comm Error'});
      },
    });
  },
  
  checkDailyAction : function (userList, notify)
  {
    var t = Tabs.Resources;
    var count = 0;
    t.getDailyAction(userList[count].userId, parseViewCourt);
  
    function parseViewCourt (rslt)
    {
      if (!rslt.ok || rslt.errMsg)
        notify ({errMsg:'Ajax Comm Error'});
      
      if(rslt.dailyActionFlag == 0)
        t.users.push(userList[count]);
      
      t.progress(count, 'pbResUserAvailCount');
      count++;
      
      if(count < userList.length)
      {
        t.getDailyAction(userList[count].userId, parseViewCourt);
      } 
      else 
      {
        notify();
      }
    }
  },
  
  // notify with gifts[] or: {errMsg:xxx}
  fetchUserList : function (notify){
  var t = Tabs.Resources;
  var userList = [];
    t.getMembersInfo(1, parseAlliancePage);
  
    function parseAlliancePage (rslt){
      if (!rslt.ok || rslt.errMsg)
        notify ({errMsg:'Ajax Comm Error'});
    var users = rslt.memberInfo;
      for(var k in users){
    userList.push({userId:users[k].userId, name:users[k].name, might:users[k].prestige, type:'alliance'});
    }
    t.progress(userList.length, 'pbResUserListCount');
    if(rslt.currentPage < rslt.noOfPages){
    t.getMembersInfo((rslt.currentPage+1), parseAlliancePage);
    } else {
    notify(userList);
    }
    }
  
  
  },
},



function addCommasWhole(nStr)
{
  nStr += '';
  x = nStr.split('.');
  x1 = x[0];
  x2 = x.length > 1 ? '.' + x[1] : '';
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(x1)) {
    x1 = x1.replace(rgx, '$1' + ',' + '$2');
  }
  return x1;
}

function encode_utf8( s )
{
  return unescape( encodeURIComponent( s ) );
}

function decode_utf8( s )
{
  return decodeURIComponent( escape( s ) );
}

function CdialogCancelContinue (msg, canNotify, contNotify, centerElement)
{
  var pop = new pbPopup ('ptcancont', 10, 10, 400,200, true, canNotify);
  if (centerElement)
    pop.centerMe(centerElement);
  else
    pop.centerMe(document.body);
  pop.autoHeight (true);  
  pop.getTopDiv().innerHTML = '<CENTER>KOC Power Bot</center>';
  pop.getMainDiv().innerHTML = '<TABLE class=ptTab align=center style="height: 100%"><TR align=center height=90%><TD>'+ msg +'</td></tr>\
      <TR align=center><TD><INPUT id=ptok type=submit value="OK" \> &nbsp; &nbsp; </td></tr></table>';
  document.getElementById('ptok').addEventListener ('click', function (){pop.destroy(false); if (canNotify) canNotify();}, false);
  pop.show(true);
}

function DisplayAlert (msg, canNotify, contNotify, centerElement, displayTime)
{
  var pop = new pbPopup ('ptcancont', 10, 10, 400, 200, true, canNotify);
  
  if (centerElement)
    pop.centerMe(centerElement);
  else
    pop.centerMe(document.body);
    
  if(displayTime) 
  {
    setTimeout(clearDisplay, displayTime * 1000);
  }
  
  pop.autoHeight (true);  
  pop.getTopDiv().innerHTML = '<CENTER>KOC Power Bot Alert</center>';
  pop.getMainDiv().innerHTML = '<TABLE class=ptTab align=center style="height: 100%"><TR align=center height=90%><TD>'+ msg +'</td></tr>\
      <TR align=center><TD><INPUT id=ptok type=submit value="OK" \> &nbsp; &nbsp; </td></tr></table>';
  document.getElementById('ptok').addEventListener ('click', function (){pop.destroy(false); if (canNotify) canNotify();}, false);
  pop.show(true);

  function clearDisplay () 
  {
    pop.show(false);
  }
}

function CdialogConfirm (msg, canNotify, contNotify, centerElement)
{
  var pop = new pbPopup ('ptcancont', 10, 10, 400,200, true, canNotify);
  
  if (centerElement)
    pop.centerMe(centerElement);
  else
    pop.centerMe(document.body);
  
  pop.getTopDiv().innerHTML = '<CENTER>KOC Power Bot</center>';
  pop.getMainDiv().innerHTML = '<TABLE class=ptTab align=center style="height: 100%"><TR align=center height=90%><TD colspan=2>'+ msg +'</td></tr>\
      <TR align=center><TD><INPUT id=pbok type=submit value="OK" \> &nbsp; &nbsp; </td><TD><INPUT id=pbcancel type=submit value="CANCEL" \> &nbsp; &nbsp; </td></tr></table>';
  document.getElementById('pbok').addEventListener ('click', function (){pop.destroy(false); if (canNotify) canNotify(this);}, false);
  document.getElementById('pbcancel').addEventListener ('click', function (){pop.destroy(false); if (canNotify) canNotify(this);}, false);
  pop.show(true);
}

function hexDump (dat)
{
  var i = 0;
  var s = [];
  while (i < dat.length) {
    asc = [];
    s.push (hex4(i));
    s.push (': ');
    for (var ii=0; ii<16; ii++) {
      c = dat.charCodeAt(i+ii);
      s.push (hex2(c));
      s.push (' ');
      if (c>31 && c<128)
        asc.push (dat.charAt(i+ii));
      else
        asc.push ('.');
    }
    s.push ('  ');
    s.push (asc.join(''))
    s.push ('\n');
    i += 16;
  }
  return s.join ('');
  function hex4(d){
    return hexDig(d>>12) + hexDig(d>>8) + hexDig(d>>4) + hexDig(d&15);
  }
  function hex2(d){
    return hexDig(d>>4) + hexDig(d&15);
  }
  function hexDig (d){
    hexdigs = '0123456789ABCDEF';
    return hexdigs.charAt(d&15);      
  }
}
 
// value is 0 to 1.0
function SliderBar (container, width, height, value, classPrefix, margin)
{
  var self = this;
  this.listener = null;
  if (value==null)
    value = 0;
  if (!margin)
    margin = parseInt(width*.05);
  this.value = value;
  if (width<20) width=20;
  if (height<5) height=5;
  if (classPrefix == null){
    classPrefix = 'slider';
    var noClass = true;
  }      
  var sliderHeight = parseInt(height/2);  
  var sliderTop = parseInt(height/4);
  this.sliderWidth = width - (margin*2);
    
  this.div = document.createElement ('div');  
  this.div.style.height = height +'px';
  this.div.style.width = width +'px';
  this.div.className = classPrefix +'Cont';
  if (noClass)
    this.div.style.backgroundColor='#ddd';
  
  this.slider = document.createElement ('div');
  this.slider.setAttribute ('style', 'position:relative;');
  this.slider.style.height = sliderHeight + 'px'
  this.slider.style.top = sliderTop + 'px';
  this.slider.style.width = this.sliderWidth +'px';
  this.slider.style.left = margin +'px';   /////
  this.slider.className = classPrefix +'Bar';
  this.slider.draggable = true;
  if (noClass)
    this.slider.style.backgroundColor='#fff';
  
  this.sliderL = document.createElement ('div');
  this.sliderL.setAttribute ('style', 'width:100px; height:100%; position:relative; ');
  this.sliderL.className = classPrefix +'Part';
  this.sliderL.draggable = true;
  if (noClass)
    this.sliderL.style.backgroundColor='#0c0';
  
  this.knob = document.createElement ('div');
  this.knob.setAttribute ('style', 'width:3px; position:relative; left:0px; background-color:#222');
  this.knob.style.height = height +'px';
  this.knob.style.top = (0-sliderTop) +'px';
  this.knob.className = classPrefix +'Knob';
  this.knob.draggable = true;
  this.slider.appendChild(this.sliderL);
  this.sliderL.appendChild (this.knob);
  this.div.appendChild (this.slider);
  container.appendChild (this.div);
  this.div.addEventListener('mousedown',  mouseDown, false);

  this.getValue = function (){
    return self.value;
  }

  this.setValue = function (val){   // todo: range check
    var relX = (val * self.sliderWidth);
    self.sliderL.style.width = relX + 'px';
    self.knob.style.left =  relX + 'px';
    self.value = val;
    if (self.listener)
      self.listener(self.value);
  }
  
  this.setChangeListener = function (listener){
    self.listener = listener;
  }

  function moveKnob (me){
    var relX = me.clientX - self.divLeft;
    if (relX < 0)
      relX = 0;
    if (relX > self.sliderWidth)
      relX = self.sliderWidth;
    self.knob.style.left = (relX - (self.knob.clientWidth/2) ) +'px';   // - half knob width !?!?
    self.sliderL.style.width = relX + 'px';
    self.value =  relX / self.sliderWidth;   
    if (self.listener)
      self.listener(self.value);
  }
  function doneMoving (){
    self.div.removeEventListener('mousemove', mouseMove, true);
    document.removeEventListener('mouseup', mouseUp, true);
  }  
  function mouseUp (me){
    moveKnob (me);
    doneMoving();
  }
  
  function mouseDown(me){
    var e = self.slider;
    self.divLeft = 0;
    while (e.offsetParent){   // determine actual clientX
      self.divLeft += e.offsetLeft;
      e = e.offsetParent;
    }
    moveKnob (me);
    document.addEventListener('mouseup',  mouseUp, true);
    self.div.addEventListener('mousemove',  mouseMove, true);
  }
  function mouseMove(me){
    moveKnob (me);
  }
}

function pause(milliseconds) 
{
  var dt = new Date();
  while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}

function CmatSimpleSound (playerUrl, container, attrs, onLoad, flashVars) 
{
  var self = this;
  this.player = null;
  this.volume = 100;
  this.isLoaded = false;
  this.onSwfLoaded = null;
  
  try {
    var div = document.createElement ('div');
    this.onSwfLoaded = onLoad;
    if (navigator.appName.toLowerCase().indexOf('microsoft')+1) {
      div.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"><param name="movie" value="'+playerUrl+'"><param name="quality" value="high"></object>';
      this.player = div.getElementsByTagName('object')[0];
    } else {
      div.innerHTML = '<embed src="'+playerUrl+'"  bgcolor="#eeeeee" allowfullscreen=false FlashVars="'+ flashVars +'" quality="high" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" ></embed>';
      this.player = div.getElementsByTagName('embed')[0].wrappedJSObject;
    }
    if (container)
      container.appendChild (div);
    else
      document.body.appendChild (div);
    for (k in attrs)
      this.player.setAttribute(k, attrs[k]);
         
    this.setVolume = function (chanNum, vol){
      if (!self.isLoaded)
        return;
      self.player.jsSetVolume (chanNum, vol);
      volume = vol;
    }
    
    this.load = function (chanNum, url, bStream, bAutoplay, bUsePolicyFile){   // loop ?
      self.player.jsLoad (chanNum, url, bStream, bAutoplay, bUsePolicyFile);
    }
    
    this.play = function (chanNum, position){
       if (this.isLoaded)
      self.player.jsPlay (chanNum, position);
    }
      
    this.stop = function (chanNum){
       if (this.isLoaded)
      self.player.jsStop (chanNum);
    }
      
    this.getStatus = function (chanNum){           // returns null if sound channel is 'empty'
     if (this.isLoaded)
      return self.player.jsGetStatus (chanNum);
    }
    
    this.debugFunc = function (msg){  // overload to use
    }
        
    this.swfDebug = function (msg){    // called by plugin
      self.debugFunc('SWF: '+ msg);
    }
    this.swfLoaded = function (){    // called by plugin when ready to go!
      self.isLoaded = true;
      self.debugFunc ('playerIsReady');
      if (self.onSwfLoaded)
        self.onSwfLoaded();
    }
    this.swfPlayComplete = function (chanNum){    // called by plugin when a sound finishes playing (overload to be notified)
    }
    this.swfLoadComplete = function (chanNum, isError){    // called by plugin when a sound finishes loading  (overload to be notified)
    }
  }
  catch (e) {
  }
}
  
function DoUnsafeWindow(func, execute_by_embed) 
{
  if(this.isChrome || execute_by_embed) 
  {
    var scr=document.createElement('script');
    scr.innerHTML=func;
    document.body.appendChild(scr);
  } 
  else 
  {
    try 
    {  
      eval("unsafeWindow."+func);
    } 
    catch (error) 
    {
      logit("A javascript error has occurred when executing a function via DoUnsafeWindow. Error description: "+error.description);
    }
  }
} 

function GetDisplayName(){
  var DisplayName = document.getElementById('topnavDisplayName');
  if(DisplayName){
    DisplayName = DisplayName.innerHTML;
  }else{
    DisplayName = null;
  }
  return DisplayName
}

//modal_maptile((tileID),(Name),(X),(Y),(Gender+Avatar),(User),(Might),(Title),(AllianceName),(null),(tileProvinceId),(tilename),(CityState),(TileLevel),(allianceId),(tileCityId),(tileUserId),(TypeName),(misted));
//modal_maptile(453323,"Heineken4",172,622,"m6","Heineken",3758930,"60","Darkness",null,21,"city","Normal",9,2136,67677,1589067,"City",false);

//koc version-572
//modal_maptile(this,307227,"NewRetard",698,326,"m8","oftheNOOBS",42318533,"90","Darkness",null,14,"city","Normal",12,2136,26654,1550996,"City",false);return false;
function DrawLevelIcons() 
{
  //var maptileRe = /modal_maptile.([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)/;
  var mapwindow=document.getElementById('mapwindow');
  if(!mapwindow) return;
  var levelIcons=document.getElementById('levelIcons');
  if(levelIcons) return;

  var ss = document.evaluate(".//a[contains(@class,'slot')]", mapwindow, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

  var idDone=false;
  
  for(var s = 0 ; s < ss.snapshotLength ; s++) 
  {
    var a = ss.snapshotItem(s);
    var onclick = a.getAttribute('id');
    
    var owner='';
    
    if(onclick) 
    {
      var tileinfo = unsafeWindow.g_mapObject.model.getTileActions(onclick)["tileClick"];
      
      if(tileinfo) 
      {
        var might = parseInt(tileinfo.might);
        var tileId = tileinfo.tileid;
        var userId = parseIntNan(tileinfo.tileuserid);
        var alliance = parseIntNan(tileinfo.allianceId);
        var dip = getDiplomacy(alliance);
        var isCity = (tileinfo.type == 'city');
        owner = tileinfo.username;
      }
    }
    
    var sp=a.getElementsByTagName('span');
    if(sp.length==0) continue;

    if(!idDone) 
    { 
      a.id='levelIcons'; 
      idDone=true; 
    }
    
    sp[0].style.color='#cc0';
    
    if (alliance == 'null' && isCity)
    {
      sp[0].style.color='#33CCFF';
    }
    else if(userId == unsafeWindow.tvuid)
    {
      sp[0].style.color='#66FF66';
    }
    else if (dip == 'hostile')
    {
      sp[0].style.color='#FF0000';
    }
    else if (alliance==Seed.allianceDiplomacies.allianceId)
    {
      sp[0].style.color='#00CC00';
    }
    else if (!isCity &&  owner != 'null') 
    {
      sp[0].style.color='#FF9900';
    }
    else if (!isCity && userId == "null") 
    {
      sp[0].style.color='#CC0033';
    }
    
    var cellText = '';
    
    if (Options.MapShowExtra) 
    {
      if (tileinfo && owner != 'null' ) 
      {
        cellText = tileinfo.level + ' : ' + owner;
        
        if(userId != unsafeWindow.tvuid)
        {
          cellText += '<br />Might:' + addCommas(might) + '<div id=mapRange_' + tileId + '><div>';
        }
        else
        {
          continue;
        }
      }
      else 
      {
        cellText = tileinfo.level;
      }
    }
    else 
    {  
      if (tileinfo && owner != 'null' ) 
      {
        cellText =  tileinfo.level + ' : ' + owner;
      }
      else 
      {
        cellText = tileinfo.level;
      }
    }
    
    sp[0].innerHTML = cellText;
    
    logit("Map: city - " + isCity);
    logit("Map: user - " + userId);
    logit("Map: type - " + userId);
    logit("Map: tileId - " + tileId);
    
    
    if(Options.FullEnable && Options.attackersRange[userId] && isCity)
    {
      var attacker = Options.attackersRange[userId];
      var range = parseIntWithDefault(attacker.range,0) + parseIntWithDefault(attacker.rangeDebuff,0);
      var siegeRange = parseIntWithDefault(attacker.siegeRange,0) + parseIntWithDefault(attacker.siegeRangeDebuff,0);
      var rangedRange = parseIntWithDefault(attacker.rangedRange,0) + parseIntWithDefault(attacker.rangedRangeDebuff,0);
      
      jQuery('#mapRange_' + tileId).html('[' + range + ',' + siegeRange + ',' + rangedRange + ']');

      var rowClass = "#47D147";
      
      switch(attacker.battleResult)
      {
        case 2: // his archers win
          rowClass = "#FF5C33";
          break;
        case 1: // his cats win
          rowClass = "#FFFF00";
          break;
        case 10: // our archers win
          rowClass = "#7094FF";
          break;
        default:
          rowClass = "#999999";
          break;
      }
      
      jQuery('#mapRange_' + tileId).css("color",rowClass);
    }
  }
}

function getJSONfromURL(url, notify) 
{
  GM_xmlhttpRequest(
  {
    method: "GET",
    url: url,
    
    onload: function(xhr) 
    {
      var response = eval("(" + xhr.responseText + ")");
      if(notify != null)
      {
        notify(response);
        
        logit("Range Import: finished download and import of ranges");
      }
    }
  });
}

var setBusy = function(value) 
{
  var loadingSymbol = jQuery("#throneSpinnyContainer");
  
  if (value) 
  {
    if (loadingSymbol.length == 0) 
    {
      logit("Spinny: now adding spinny to display");
      jQuery("#pb_outer").append("<div id=throneSpinnyContainer><div class='spinny'></div></div>")
    }
  } 
  else 
  {
    loadingSymbol.remove()
  }
};

function addOutgoingMarch(params, rslt)
{
  var timediff = parseInt(rslt.eta) - parseInt(rslt.initTS);
  var ut = unsafeWindow.unixtime();
  
  var unitsarr = [];
  for (j in unsafeWindow.unitcost)
    unitsarr.push(0);
  for(i = 0; i <= unitsarr.length; i++)
    if(params["u"+i])
      unitsarr[i] = params["u"+i];

  var resources=[0,0,0,0,0,0,0,0,0,0,0,0,0];
  
  for(i = 0; i <= unitsarr.length; i++)
  {
    if(params["u"+i])
    {
      unitsarr[i] = params["u"+i];
    }
  }
            
  resources[0] = params.gold;
  for(i = 1 ; i <= 5 ; i++)
  {
    resources[i] = params["r"+i];
  }

  var currentcityid = params.cid;
  unsafeWindow.attach_addoutgoingmarch(rslt.marchId, rslt.marchUnixTime, ut + timediff, params.xcoord, params.ycoord, unitsarr, params.type, params.kid, resources, rslt.tileId, rslt.tileType, rslt.tileLevel, currentcityid, true);

  CheckUpdateSeed(rslt);
}

function doMarch(params, marchType, priority, marchSucceed, marchFailed, failureCallback)
{
  var _ajaxCall = function ()
  {
    var profiler = new CM.Profiler("ResponseTime", "march.php");
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
    { 
      method: "post",
      parameters: params,
      loading: true,
      crest: true,
      priority: priority,

      onSuccess: function (transport) 
      {   
        profiler.stop();
        var rslt = eval("(" + transport.responseText + ")");
        
        if (rslt.ok) 
        {
          addOutgoingMarch(params, rslt);
          
          CheckUpdateSeed(rslt);

          if(marchSucceed)
          {
            marchSucceed(rslt);
          }
        } 
        else 
        {
          if (rslt.user_action) 
          {
            var user_action = 
            {
              marchWarning: function() 
              {
                logit('Captcha: [' + marchType + '] captcha warning');
                actionLog('Captcha: [' + marchType + '] captcha warning');
              },
              marchCaptcha: function() 
              {
                actionLog('Captcha: [' + marchType + '] triggered captcha');
                logit('Captcha: [' + marchType + '] triggered captcha');
                startCaptcha();
              },
              backOffWaitTime: function() 
              {
                logit('Captcha: [' + marchType + '] back off time - ' + rslt.wait_time);
                actionLog('Captcha: [' + marchType + '] back off time - ' + rslt.wait_time);
                params.tt = rslt.tt;
                setTimeout(_ajaxCall, rslt.wait_time * 1000)
              }
            };
            user_action[rslt.user_action].call();
          }
          
          if(marchFailed)
          {
            marchFailed(rslt);
          }
        }
      },
      
      onFailure: function () 
      {
        profiler.stop();
        
        if(failureCallback)
        {
          failureCallback(rslt);
        }
      }
    }, true); 
  }
  
  _ajaxCall();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support: Requests
/////////////////////////////////////////////////////////////////////////////////////////////////////////

function SendAjaxRequest2 (url, opts)
{
  var headers = 
  {
    'X-Requested-With': 'XMLHttpRequest',
    'X-Prototype-Version': '1.6.1',
    'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
  };
  var ajax = null;   
  
  if (window.XMLHttpRequest)
    ajax=new XMLHttpRequest();
  else
    ajax=new ActiveXObject("Microsoft.XMLHTTP");   
  
  if (opts.method==null || opts.method=='')
    method = 'GET';
  else
    method = opts.method.toUpperCase();    
  
  if (method == 'POST')
  {
    headers['Content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
  } 
  else if (method == 'GET')
  {
    addUrlArgs (url, opts.parameters);
  }    
  
  ajax.onreadystatechange = function()
  {
    // ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; states 0-4
    if (ajax.readyState==4) 
    {
      if (ajax.status >= 200 && ajax.status < 305)
        if (opts.onSuccess) 
          opts.onSuccess(ajax);
        else
          if (opts.onFailure) 
            opts.onFailure(ajax);
    } 
    else 
    {
      if (opts.onChange) 
        opts.onChange (ajax);
    }
  }
  
  ajax.open(method, url, true); // always async!
  
  for (var k in headers)
    ajax.setRequestHeader (k, headers[k]);
    
  if (matTypeof(opts.requestHeaders)=='object')
    for (var k in opts.requestHeaders)
      ajax.setRequestHeader (k, opts.requestHeaders[k]);
  
  if (method == 'POST')
  {
    var a = [];
    for (k in opts.parameters)
    {
      if(matTypeof(opts.parameters[k]) == 'object')
      {
        for(var h in opts.parameters[k])
        {
          if(matTypeof(opts.parameters[k][h]) == 'object')
          {
            for(var i in opts.parameters[k][h])
            {
              if(matTypeof(opts.parameters[k][h][i]) == 'object')
              {
                for(var j in opts.parameters[k][h][i])
                {
                  a.push (k+'['+h+']['+i+']['+j+'] ='+ opts.parameters[k][h][i][j] );
                }
              } 
              else
              {
                a.push (k+'['+h+']['+i+']'+' ='+ opts.parameters[k][h][i]);
              }
            }
          } 
          else
          {
            a.push (k+'['+h+'] ='+ opts.parameters[k][h] );
          }
        }
      } else
      a.push (k +'='+ opts.parameters[k] );
    }
    
    ajax.send (a.join ('&'));
  } 
  else 
  {
    ajax.send();
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support: Options
/////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function saveSalvageData ()
{
    var serverID = getServerId();
    setTimeout (function (){GM_setValue ('SalvageDataMM2_'+serverID, JSON2.stringify(salvageData));}, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function saveAttackOptions ()
{
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('AttackOptions_'+serverID, JSON2.stringify(AttackOptions));}, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function readAttackOptions ()
{
  var serverID = getServerId();
  s = GM_getValue ('AttackOptions_'+serverID);
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts)
    {
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          AttackOptions[k][kk] = opts[k][kk];
      else
        AttackOptions[k] = opts[k];
    }
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function saveFarmOptions() 
{
    var serverID = getServerId();
    setTimeout(function () 
    {
        GM_setValue('FarmOptions_' + serverID, JSON2.stringify(FarmOptions));
    }, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function readFarmOptions() 
{
    var serverID = getServerId();
    s = GM_getValue('FarmOptions_' + serverID);
    if (s != null) 
    {
        opts = JSON2.parse(s);
        for (k in opts) 
        {
            if (matTypeof(opts[k]) == 'object') for (kk in opts[k])
            FarmOptions[k][kk] = opts[k][kk];
            else FarmOptions[k] = opts[k];
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function saveThroneOptions() 
{
    var serverID = getServerId();
    setTimeout(function () 
    {
        GM_setValue('ThroneOptions_' + serverID, JSON2.stringify(ThroneOptions));
    }, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function readThroneOptions() 
{
    var serverID = getServerId();
    s = GM_getValue('ThroneOptions_' + serverID);
    if (s == null || s == undefined)
    {
      s = GM_getValue ('ThroneOptions_'+132);
    }
    if (s != null) 
    {
        opts = JSON2.parse(s);
        for (k in opts) 
        {
            if (matTypeof(opts[k]) == 'object') for (kk in opts[k])
            ThroneOptions[k][kk] = opts[k][kk];
            else ThroneOptions[k] = opts[k];
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support: Range
/////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function troopRange(attacker, defender, unitType, assumeAttackSacrifice) 
{
  switch(unitType)
  {
    case 12:
      var range = unsafeWindow.unitstats['unt12'][4];
      break;
    case 10:
      var range = unsafeWindow.unitstats['unt10'][4];
      break;
    case 6:
      var range = unsafeWindow.unitstats['unt6'][4];
      break;
  }

  var percentage = (parseIntWithDefault(attacker.range, 0) - parseIntWithDefault(defender.rangeDebuff, 0));
  
  // check if this is archers or siege and add in the relevant bonuses 1200 is base for archers, anything above that is siege (we are not worried about rams)
  if(unitType != 6) 
  {
    percentage += (parseIntWithDefault(attacker.siegeRange, 0) - parseIntWithDefault(defender.siegeRangeDebuff, 0));
  } 
  else 
  {
    percentage += (parseIntWithDefault(attacker.rangedRange, 0) - parseIntWithDefault(defender.rangedRangeDebuff, 0));
  }
  
  // we cannot reduce range by more than 25%
  if(percentage < -25) 
  {
    percentage = -25;
  }
  
  //this is the max range that is allowed
  if(percentage > 150)
  {
      percentage = 150;
  }
  
  // sacrifice modifies the base percentage so all boosts work on the new base, it does not add like a fletch or tr type addition
  if(assumeAttackSacrifice)
  {
    range = range * 1.4;
  }
  
  // TODO : we also need to add in the new fletch boost at some point although this does not appear to be working yet
  
  return range * (100 + (5 * parseIntWithDefault(attacker.fletch, 12)) + parseIntWithDefault(percentage, 0)) / 100;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support: Marches
/////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isCityAttack(march) 
{
  var cityAttack = false;
  
  var city = Cities.byID[march.toCityId];
  
  if(march.marchType == 4 && city.tileId == march.toTileId && march.pid != unsafeWindow.tvuid) 
  {
    cityAttack = true;
  }
  
  return cityAttack;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isCityScouting(march) 
{
  var cityScouting = false;
  
  var city = Cities.byID[march.toCityId];
  
  if(march.marchType == 3 && city.tileId == march.toTileId && march.pid != unsafeWindow.tvuid) 
  {
    cityScouting = true;
  }
  
  return cityScouting;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isCityMarch(march) 
{
  var cityMarch = false;
  
  var city = Cities.byID[march.toCityId];
  
  if(city.tileId == march.toTileId && march.pid != unsafeWindow.tvuid) 
  {
    cityMarch = true;
  }
  
  return cityMarch;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isLandedReinforcement(march, cityId) 
{
  var landedReinforcement = false;
  var now = unixTime();
  var city = Cities.byID[cityId];
  
  if(march.marchType == CM.MARCH_TYPES.MARCH_TYPE_REINFORCE && now > march.destinationUnixTime && city.tileId == march.toTileId) 
  {
    landedReinforcement = true;
  }
  
  return landedReinforcement;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isRangeMarch(march) 
{
  var rangeMarch = false;
  
  var rangeCount = parseIntWithDefault(march.unit6Count, 0) + parseIntWithDefault(march.unit10Count, 0) + parseIntWithDefault(march.unit12Count, 0);
  
  if(rangeCount > Options.rangeReinforcementThreshold) 
  {
    rangeMarch = true;
  }
  
  return rangeMarch;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isDefendAttack(march) 
{
  var defendAttack = false;
  
  if(march.marchType == 4)
  {
    var marchCombination =  ( 
                              parseIntWithDefault(march.unts.u3,0) == 11 && 
                              parseIntWithDefault(march.unts.u4,0) == 1 && 
                              parseIntWithDefault(march.unts.u5,0) == 1 &&
                              parseIntWithDefault(march.unts.u6,0) >= 1 &&
                              ( 
                                parseIntWithDefault(march.unts.u7,0) == 1 || 
                                parseIntWithDefault(march.unts.u7,0) == 11 
                              )
                            );
    
    if(enableCheck(march.aid) && marchCombination) 
    {
      defendAttack = true;
    }
  }

  return defendAttack;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function isChangeThrone(march) 
{
  var changeThrone = false;
  
  if(march.marchType == 4)
  {
    var marchCombination =  ( 
                              parseIntWithDefault(march.unts.u7,0) == 11 && 
                              parseIntWithDefault(march.unts.u4,0) == 1 && 
                              parseIntWithDefault(march.unts.u5,0) == 1 &&
                              parseIntWithDefault(march.unts.u6,0) >= 1 &&
                              ( 
                                parseIntWithDefault(march.unts.u3,0) == 1 || 
                                parseIntWithDefault(march.unts.u3,0) == 11 
                              )
                            );
    
    if(enableCheck(march.aid) && marchCombination) 
    {
      changeThrone = true;
    }
  }
  
  return changeThrone;
}

function isCloseAttack(march, timeGap) 
{
  var closeAttack = false;
  var now = unixTime();
  
  if(parseIntNan(march.arrivalTime) < (parseIntNan(now) + parseIntWithDefault(timeGap, 120))) 
  {
    closeAttack = true;
  }
  
  return closeAttack;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getRallypointLevel(cityId)
{
  var rallyPointLevel = 0;
  
  if(cityId.toString().substring(0,4) != "city")
  {
    logit("Debug: cityId not starting with 'city' - " + cityId );
    cityId = "city" + cityId;
  }
  
  for (var o in Seed.buildings[cityId])
  {
    var buildingType = parseInt(Seed.buildings[cityId][o][0]);
    var buildingLevel = parseInt(Seed.buildings[cityId][o][1]);
    
    if (buildingType == CM.BUILDING_TYPES.RALLY_POINT) 
    {
      rallyPointLevel = parseInt(buildingLevel);
      break;
    }
  }
  
  return rallyPointLevel;
}
  
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getActiveMarches(cityId)
{
  if(cityId.toString().substring(0,4) != "city")
  {
    logit("Debug: cityId not starting with 'city' - " + cityId );
    cityId = "city" + cityId;
  }

  var slots=0;
  
  for (z in Seed.queue_atkp[cityID]) 
  {
    slots++;
  }

  if  (Seed.queue_atkp[cityID].toSource() == "[]")
  {
    slots=0;
  }
  
  return slots;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getMaxMarches(cityId)
{
  if(cityId.toString().substring(0,4) == "city")
  {
    logit("Debug: cityId starting with 'city' - " + cityId );
    var cityId = cityId.substring(4);
  }

  var maxMarches = getRallypointLevel(cityId);
  
  if(maxMarches > 11)
  {
    maxMarches = 11;
  }
  
  if(Seed.cityData.city[cityId].isPrestigeCity)
  {
    maxMarches += 3
  }
  
  return maxMarches;
}
  
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getMaxMarchSize(cityId)
{
  if (cityId.toString().substring(0,4) == "city")
  {
    logit("Debug: cityId starting with 'city' - " + cityId );
    var cityId = cityId.substring(4);
  }

  var rallyPointLevel = getRallypointLevel(cityId);
  var maxMarchSize = 0;
  var prestigeBaseBoost = 0.50;
  var marchBonus = 1.0;
  var prestigeBonus = 1.0;
  
  if (rallyPointLevel <= 10)
  {
    maxMarchSize = rallyPointLevel * 10000;
  }
  else if (rallyPointLevel == 11)
  {
    maxMarchSize = 15 * 10000;
  }
  else if (rallyPointLevel == 12)
  {
    maxMarchSize = 20 * 10000;
  }

  logit("Debug: march size (base) - " + maxMarchSize);

  if(Seed.cityData.city[cityId].isPrestigeCity)
  {
    var ascendLevel = Seed.cityData.city[cityId].prestigeInfo.prestigeLevel;
    prestigeBonus += (prestigeBaseBoost + (+ascendLevel * 0.05));

    logit("Debug: march size (bonus) - prestigeBonus " + prestigeBonus);
    
    // check if we have the march boost blessing enabled
    if(Seed.cityData.city[cityId].prestigeInfo.blessings)
    {
      if(Seed.cityData.city[cityId].prestigeInfo.blessings.indexOf(207) != -1)
      {
        prestigeBonus += 0.1;
        logit("Debug: march size (bonus) - prestigeBonus (blessing)" + prestigeBonus);
      }
    }
 
    logit("Debug: march size (bonus) - " + marchBonus);

  }
  
  maxMarchSize *= prestigeBonus;
  maxMarchSize *= marchBonus;
  
  maxMarchSize = Math.floor(maxMarchSize);
  
  logit("Debug: march size - " + maxMarchSize);
  
  return maxMarchSize;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Name :
/////////////////////////////////////////////////////////////////////////////////////////////////////////
function getFreeMarchSlots(cityId)
{
  if(cityId.toString().substring(0,4) != "city")
  {
    logit("Debug: cityId not starting with 'city' - " + cityId );
    cityId = "city" + cityId;
  }

  var freeMarches = getMaxMarches(cityId);
  
  var currentMarches = 0;
  
  for (z in Seed.queue_atkp[cityID]) 
  {
    currentMarches++;
  }

  if  (Seed.queue_atkp[cityID].toSource() == "[]")
  {
    currentMarches = 0;
  }
  
  return (freeMarches - currentMarches);
}  

  
var DeleteReports = 
{
  deleting : false,
  desertionCheckComplete : true,

  init : function()
  {
    var t = DeleteReports;
    setInterval(t.startdeletereports, 2 * 60 * 1000);
    setTimeout(t.startdeletereports, 10);
  },
  
  startdeletereports : function()
  {
    var t = DeleteReports;
    //logit("Checking reports - desertion flag - " + t.desertionCheckComplete);
    //logit("Checking reports - deletion flag - " + t.deleting);
    if(!t.deleting && (Options.DeleteMsg || Options.DeleteMsgs0 || Options.DeleteMsgs1 || Options.DeleteMsgs2 || Options.desertionChatEnabled))
    {
      t.deleting = true;
      t.desertionCheckComplete = false;
      t.fetchreport(0, t.checkreports);
    }
  },
    
  fetchreport : function(pageNo, callback)
  {
    var t = DeleteReports;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    
    if(pageNo > 1)
      params.pageNo = pageNo;
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/listReports.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) 
      {
        callback(rslt);
      },
      
      onFailure: function () 
      {
        callback();
      },
    });
  },
  
  checkreports : function(rslt)
  {
    var t = DeleteReports;
    
    if(!rslt.ok)
    {
      t.deleting = false;
      return;
    }

    //logit(JSON2.stringify(rslt,null,2));
    
    if(!rslt.arReports)
    {
      logit("Report fault - " + JSON2.stringify(rslt,null,2));
      t.deleting = false;
      t.desertionCheckComplete = true;
      return;
    }
    
    if(rslt.arReports.length < 1)
    {
      logit("CR stopped arreports < 1");
      t.deleting = false;
      return;
    }
    
    var reports = rslt.arReports;
    var totalPages = rslt.totalPages;
    
    if (rslt.totalPages > 30)
      var totalPages = 30;
    var deletes1 = new Array();
    var deletes0 = new Array();
    
    for(k in reports)
    {
      if(Options.desertionChatEnabled && (reports[k].eventType == 70) && ((t.desertionCheckComplete == false) || (reports[k].reportStatus == 2)))
      {
        t.handleDesertionReport(reports[k].reportId);
      }

      if(Options.DeleteMsg)
      {
        if((reports[k].marchType==4 || reports[k].marchType==9) && reports[k].side0PlayerId==0 && reports[k].side0TileType > 50)
        {
          deletes1.push(k.substr(2));
        }
        else if(reports[k].marchType==1 && t.isMyself(reports[k].side1PlayerId))
        {
          deletes1.push(k.substr(2));
        }
      }
      
      if (Options.DeleteMsgs0)
      {
        if(reports[k].marchType==1 && !t.isMyself(reports[k].side1PlayerId))
        {
          deletes0.push(k.substr(2));
        }
      }
      
      if (Options.DeleteMsgs1)
      {
        if((reports[k].side0TileType <= 50 || reports[k].side0TileType==54)&& reports[k].side0PlayerId==0 && (reports[k].eventType != 70))
        {
          deletes1.push(k.substr(2));
        }
      }
      
      // Auto deletion of crest marches
      if (Options.DeleteMsgs2)
      {
        for(i in CrestData) 
        {
          if(reports[k].side0XCoord == CrestData[i].X && reports[k].side0YCoord == CrestData[i].Y && reports[k].marchType==4 && t.isMyself(reports[k].side1PlayerId)) 
          {
            //logit(JSON2.stringify(reports[k], null, 2));
            deletes1.push(k.substr(2));
          }
        }
      }

      if(enableCheck(reports[k].side1AllianceId) && !t.isMyself(reports[k].side1PlayerId)) 
      {
        deletes1.push(k.substr(2));
      }
    }
    t.desertionCheckComplete = true;

    if(deletes1.length > 0 || deletes0.length > 0){
      t.deleteCheckedReports(deletes1, deletes0);
    } else {
      t.deleting = false;
      return;
    }
  },
    
  handleDesertionReport: function(reportid) 
  {
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.rid = reportid;
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/fetchCityEventReport.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      onSuccess: function (rslt) 
      {
        //logit(JSON2.stringify(rslt,null,2));
        if (rslt.ok) 
        {
          //var reportDate = formatDateByUnixTime(rslt.index.reportUnixTime);
          var reportDate = rslt.index.reportUnixTime;
          var reportNumber = rslt.index.cityEventReportId;
          var production = Math.floor(rslt.detail.r1production);
          var consumption = Math.floor(rslt.detail.r1consumption);
          var deficit = production - consumption;
          var cityId = rslt.index.cityId;
          var cityNumber = unsafeWindow.g_mapObject.getSlotCity(1, cityId);
          var cityName = "";
          for (var i = 0; i < Seed.cities.length; i++) 
          {
            var city = Seed.cities[i];
            
            if (city[0] == cityId) 
            {
              cityName = city[1];
              xCoord = city[2];
              yCoord = city[3];
              break
            }
          }
          var lostTroops = [];
          var units = rslt.detail.units;
          for (var unitKey in units) 
          {
            var lost = units[unitKey];
            var after = rslt.detail.newUnitCounts ? rslt.detail.newUnitCounts[unitKey] : "-";
            var before = rslt.detail.oldUnitCounts ? rslt.detail.oldUnitCounts[unitKey] : "-";
            
            if (lost > 0) 
            {
              var unitId = unitKey.substring(1);
              //var img = "img/units/unit_" + unitId + "_30_s34.jpg";
              var unitName = unsafeWindow.unitcost["unt" + unitId][0];
              var unit = {};
              //unit.image = img;
              unit.name = unitName;
              unit.before = before;
              unit.after = after;
              unit.lost = lost;
              lostTroops.push(unit)
            }
          }
          
          var now = unixTime();
          var reportModel = 
          {
            date: reportDate,
            secondsAgo : (parseInt(now) - parseInt(reportDate)),
            reportNumber: reportNumber,
            city: 
            {
              name: cityName,
              number: cityNumber,
              location: xCoord + "," + yCoord
            },
            lostTroops: lostTroops,
            food: 
            {
              produced: production,
              consumed: consumption,
              deficit: deficit
            }
          };
          
          if(reportModel.secondsAgo < (10 * 60)) 
          {
            var msg = "<b>Troops Deserting!!!!</b><br>";
            msg += "Troops lost from city " + reportModel.city.name + "(" + reportModel.city.location + ")<br>";
            msg += "Reported " + reportModel.secondsAgo + " seconds ago<br>";
            msg += "<i>Troop losses:</i><br>";
            
            for(unit in reportModel.lostTroops) 
            { 
              if(reportModel.lostTroops.hasOwnProperty(unit))
                msg += reportModel.lostTroops[unit].name + ":" + reportModel.lostTroops[unit].lost + "<br>";
            }
            
            msg += "Food deficit (per hr) <b>" + reportModel.food.deficit + "</b><br>";
            sendChat ("/a " + msg);
          }
        }
      },
      
      onFailure: function () 
      {
          
      }
    })
  },
  
  deleteCheckedReports : function(deletes1, deletes0)
  {
    var t = DeleteReports;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.s1rids = deletes1.join(",");
    params.s0rids = deletes0.join(",");
    params.cityrids = '';
    
    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/deleteCheckedReports.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      priority: true,
      
      onSuccess: function (rslt) 
      {
        if(rslt.ok)
        {
          Seed.newReportCount = parseInt(Seed.newReportCount) - parseInt(deletes1.length) - parseInt(deletes0.length);
          actionLog('Deleted: ' +parseInt(deletes1.length + deletes0.length)+' reports');
        }
        
        t.fetchreport(0, t.checkreports);
      },
      
      onFailure: function () 
      {
      },
    });
  },
  
  isMyself: function(userID)
  {
    var t = DeleteReports;
    if(!Seed.players["u"+userID])
      return false;
    if(Seed.players["u"+userID].n == Seed.player.name)
      return true;
    else
      return false;
    return false;
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Apothecary
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Apothecary = 
{
  tabOrder : 591,                    // order to place tab in top bar
  tabDisabled : false, // if true, tab will not be added or initialized
  tabLabel : 'Apothecary',            // label to show in main window tabs
  cities : [],
  pop : null,
  pop2 : null,
  myDiv : null,
  timer : null,
  
  init : function (div){    // called once, upon script startup
    var t = Tabs.Apothecary;
    t.myDiv = div;
    var m = '<DIV class=pbStat >APOTHECARY TAB</div><table width=100% height=0% class=pbTab><tr align=center >';
    m += '<td><input type=submit id=pbapothecary_power value="Auto Heal = '+(ApothecaryOptions.Active?'ON':'OFF')+'" /></td>\
          <td><input type=submit id=pbapothecary_show value="Show" /></td></tr></table>';
  m += '<DIV class=pbStat id=pbapothecary_options >OPTIONS</div></div><table></tr>\
        <td>Keep Gold : <INPUT type=text id="pbapothecary_gold" size=6 value='+ApothecaryOptions.goldkeep+' /></td>\
      <td colspan=4><span id="pbapothecary_citysel"></span></td></tr><tr>\
      <td>Troop type : <SELECT id="pbapothecary_troops"><option value=0>--Select--</options>';
  for (y in unsafeWindow.unitcost)
    m += '<option value="'+y.substr(3)+'">'+unsafeWindow.unitcost[y][0]+'</option>';
    m += '</select></td>\
      <td>Min.: <INPUT id=pbapothecary_min type=text size=4 \></td>\
      <td><INPUT type=checkbox id=pbapothecary_maxcheck /> Max.: <INPUT id=pbapothecary_max type=text size=4 DISABLED \></td>\
      <td><INPUT type=submit id=pbapothecary_save value=Add /></td>';
  m += '</tr></table>';
    div.innerHTML = m;
    $("pbapothecary_gold").addEventListener('change', function(){
    ApothecaryOptions.goldkeep = parseIntNan(this.value);
  },false);
    $("pbapothecary_maxcheck").addEventListener('click', function(){
    $("pbapothecary_max").disabled = !($("pbapothecary_maxcheck").checked);
  },false);
    $("pbapothecary_save").addEventListener('click', function(){
    t.e_addqueue();
  },false);
  $("pbapothecary_power").addEventListener('click', function(){
    t.e_toggleswitch(this);
  },false);
  $("pbapothecary_show").addEventListener('click', function(){
    t.e_displayarray();
  },false);
    for (var cid in Cities.byID){
    var city = 'city'+cid;
    var x = Cities.byID[cid].idx;
    t.cities[x] = true;
    for (var y in Seed.buildings[city]) {
        if (Seed.buildings[city][y][0] == 21){
        t.cities[x] = false;
        continue;
      }
      }
  }
  t.citysel = new CdispCityPicker ('pbapo_sel', document.getElementById("pbapothecary_citysel"), true, null, 0, t.cities);
  t.timer = setTimeout(t.loop,5000);
  },
  
  e_addqueue : function (){
    var t = Tabs.Apothecary;
    var city = t.citysel.city.idx;
    var troopsel = $("pbapothecary_troops").value;
    var min = parseIntNan($("pbapothecary_min").value);
    var max = parseIntNan($("pbapothecary_max").value);
    var max_sel = $("pbapothecary_maxcheck").checked;

    try 
    {
      if((troopsel < 1 || min < 1) || (max_sel && max < 1) || (max_sel && (max < min)))
        throw "Incomplete/Invalid Input!";
      ApothecaryOptions.city[city].push({troop:troopsel,min:min,max:max,max_sel:max_sel});
      saveApothecaryOptions();
      $('pbapothecary_options').style.background ='#99FF99';
      setTimeout(function(){ ($('pbapothecary_options').style.background =''); }, 1000);
    } 
    catch (e)
    {
      $('pbapothecary_options').style.background ='#FF0000';
      setTimeout(function(){ ($('pbapothecary_options').style.background =''); }, 1000);
    }
  },
  
  e_displayarray : function()
  {
    var t = Tabs.Apothecary;
    if(t.pop == null)
    t.pop = new pbPopup('pbapothecary_pop',0,0,400,500,true,function(){t.pop.destroy(); t.pop = null;});
    t.pop.getTopDiv().innerHTML = '<DIV><center>Auto Heal Array</center></div>';
    var m = '<table><tr>';

    for (var city in ApothecaryOptions.city)
    {
      if(!Cities.cities[city] || ApothecaryOptions.city[city].length < 1) continue;
      
      m += '<td colspan=2><b>'+Cities.cities[city].name+'</b></td>\
          <td>Minimum</td><td>Maximum</td><tr>';
      
      for(var i=0; i<ApothecaryOptions.city[city].length; i++)
      {
        var info = ApothecaryOptions.city[city][i];
        m += '<td>'+(i+1)+'</td><td>'+unsafeWindow.unitcost['unt'+info.troop][0]+'</td>\
            <td>'+info.min+'</td><td>'+info.max+'</td><td>'+strButton20('Edit','title="Apothecary edit" onclick="pbapo(this,'+i+','+city+')"')+'</td><td>'+strButton20('Delete','title="Apothecary delete" onclick="pbapo(this,'+i+','+city+')"')+'</td>';
        m += '</tr><tr>';
      }
      
      m += '</tr><tr>';
    }
    
    t.pop.getMainDiv().innerHTML = m;
    unsafeWindow.pbapo = t.display_action;
    t.pop.show(true);
  },
  
  display_action : function(obj,id,city)
  {
    var t = Tabs.Apothecary;
    var evt = null;
    if(obj.title.indexOf("edit") > 0)
      evt = "edit";
    if(obj.title.indexOf("delete") > 0)
      evt = "delete";
    if(evt == null || id == null) return;
    if(evt == "delete"){
      ApothecaryOptions.city[city].splice(id,1);
    }
    if(evt == "edit"){
      t.display_edit(id,city);
    }
    saveApothecaryOptions();
    t.e_displayarray();
  },
  
  display_edit : function(id, city)
  {
    var t = Tabs.Apothecary;
      if(t.pop2 == null)
      t.pop2 = new pbPopup('pbapodisp_pop',410,0,300,150,true,function(){t.pop2.destroy(); t.pop2 = null;});
    var m = '<table><tr><td><b>'+Cities.cities[city].name+'</b></td></tr>';
    var info = ApothecaryOptions.city[city][id];
    m += '<tr><td>Troop Type: </td><td>'+unsafeWindow.unitcost['unt'+info.troop][0]+'</td></tr>\
        <tr><td>Minimum: </td><td><INPUT id=pbapodisp_min type=text size=4 value="'+info.min+'" \>\
        <tr><td><INPUT type=checkbox id=pbapodisp_maxcheck '+(info.max_sel?'CHECKED':'')+' /> Maximum: </td><td><INPUT id=pbapodisp_max type=text size=4 value="'+info.max+'" '+(info.max_sel?'':'DISABLED')+' \></td></tr>\
        <tr><td><INPUT type=submit id=pbapodisp_save value=Save /></td></tr>';
    t.pop2.getMainDiv().innerHTML = m;
    t.pop2.show(true);
    $('pbapodisp_save').addEventListener('click', function(){
      var min = parseIntNan($("pbapodisp_min").value);
      var max = parseIntNan($("pbapodisp_max").value);
      var max_sel = $("pbapodisp_maxcheck").checked;
      if(min < 1 || (max_sel && max < 1) || (max_sel && (max < min))){
        alert("Invalid/Incorrect input!");
        return;
      }
      info.min = min;
      info.max = max;
      info.max_sel = max_sel;
      saveApothecaryOptions();
      t.pop2.show(false);
      t.e_displayarray();
    },false);
  },
  
  loop : function(){
    var t = Tabs.Apothecary;
    clearTimeout(t.timer);
    if(!ApothecaryOptions.Active) return;
    for (var city in ApothecaryOptions.city){
    if(!Cities.cities[city] || ApothecaryOptions.city[city].length < 1) continue;
    if(t.cities[city]) continue; //Skip if Apothecary doesn't exist
    if(Seed.queue_revive['city'+Cities.cities[city].id].length > 0) continue; //Skip city if queue is full
    if(Seed.citystats["city" + Cities.cities[city].id].gold[0] < parseInt(ApothecaryOptions.goldkeep)) continue; //Skip if gold is less than reserve
    for(var i=0; i<ApothecaryOptions.city[city].length; i++){
      var info = ApothecaryOptions.city[city][i];
      var cid = Cities.cities[city].id;
      var amt = 0;
      if(Seed.woundedUnits['city'+cid]['unt'+info.troop] < info.min) continue;
      if(Seed.woundedUnits['city'+cid]['unt'+info.troop] > info.max && info.max_sel){
        amt = info.max;
      } else {
        amt = Seed.woundedUnits['city'+cid]['unt'+info.troop];
      }
      if(cid > 0 && info.troop > 0 && amt > 0){
        t.do_revive(cid,info.troop,amt);
        break;
      }
    }
  }
  t.timer = setTimeout(t.loop, 10000);
  },
  
  e_toggleswitch : function(obj){
    var t = Tabs.Apothecary;
  if(ApothecaryOptions.Active){
    obj.value = "Auto Heal = OFF";
    ApothecaryOptions.Active = false;
    clearTimeout(t.timer);
  } else {
    obj.value = "Auto Heal = ON";
    ApothecaryOptions.Active = true;
    t.timer = setTimeout(t.loop,5000);
  }
  saveApothecaryOptions();
  },
  
  do_revive : function(currentcityid,unitId,num,notify){
    var t = Tabs.Apothecary;
  var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
  params.cid = currentcityid;
    params.type = unitId;
    params.quant = num;
    params.apothecary = true;
  var time = CM.RevivalModel.getRevivalStats(unitId, num).time;

  new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/train.php" + unsafeWindow.g_ajaxsuffix, {
    method: "post",
    parameters: params,
    onSuccess: function(rslt) {
      if (rslt.ok) {
      for (var i = 1; i < 5; i++) {
        var resourceLost = parseInt(unsafeWindow.unitcost["unt" + unitId][i]) * 3600 * parseInt(num);
        if(rslt.gamble) resourceLost = resourceLost*rslt.gamble[i];
        unsafeWindow.seed.resources["city" + currentcityid]["rec" + i][0] = parseInt(unsafeWindow.seed.resources["city" + currentcityid]["rec" + i][0]) - resourceLost;
      }
      if (!rslt.initTS) {
        rslt.initTS = unixTime() - 1;
      }
      Seed.queue_revive["city" + currentcityid].push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + time, 0, time, null]);
      var cost = CM.RevivalModel.getRevivalStats(unitId, num).cost;
      Seed.citystats["city" + currentcityid].gold[0] -= parseInt(cost);
      unsafeWindow.update_gold();
      CM.WoundedModel.sub(tid, num);
      } else {
      
      }
    },
  });
  },
  
  hide : function (){
    var t = Tabs.Apothecary;
  },
  
  show : function (){
    var t = Tabs.Apothecary;
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Combat
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Combat = 
{
  myDiv: null,
  tabOrder: 400,
  troops: [{},{}], //Array[Defender, Attacker]
  active: [{},{}],
  lost: [{},{}],
  total: [],
  stats: unsafeWindow.unitstats,   //  Life, Attack, Defense, Speed, Range, Load
  priority: [[3,7,8,4,5,6,2,1,9,11,10,12],[12,10,6,3,7,8,4,5,2,1,9,11]],
  round: 0,
  range: [0,0,0], //[Defender, Attacker, Max]
  distance: [{},{}], // [Defender, Attacker]
  speed: [0,0], // [Defender max, Attacker max]
  start: 0,
  pop : null,
  
  init: function(div){
    var t = Tabs.Combat;
    t.myDiv = div;
    var m = '<table><TR><TD colspan=2><b>Attacking</b>&nbsp;&nbsp;<INPUT id=pbcombat_1 type=submit value=Research></td><TD colspan=2><b>Defending</b>&nbsp;&nbsp;<INPUT id=pbcombat_0 type=submit value=Research></td></TR>';
    for(var troops in unsafeWindow.unitcost){
      var name = unsafeWindow.unitcost[troops][0];
      m+='<tr><td>'+name+' :</td><td><input type=text id="pbcombata_'+troops+'" /></td><td>'+name+' :</td><td><input type=text id="pbcombatd_'+troops+'" /></td></tr>';
    }
    m+='</table><DIV id=pbcombat_rslt></div>';
    t.myDiv.innerHTML = m;
    
    for(var troops in unsafeWindow.unitcost){
      document.getElementById('pbcombata_'+troops).addEventListener('change', t.e_calculate, false);
      document.getElementById('pbcombatd_'+troops).addEventListener('change', t.e_calculate, false);
    }
    document.getElementById('pbcombat_1').addEventListener('click', function() t.e_research(1),false);
    document.getElementById('pbcombat_0').addEventListener('click', function() t.e_research(0),false);
  },
  
  e_research : function(side){
    var t = Tabs.Combat;
    t.pop = new pbPopup ('pbcombatresearch', 0, 0, 270, 250, true, function(){t.c_ratio(); t.pop.destroy();});
    t.pop.centerMe (mainPop.getMainDiv()); 
    t.pop.getTopDiv().innerHTML = '<CENTER><B>Research Levels</b>: '+ (side?'Attacker':'Defender') +'</center>';
    var m = '<DIV><TABLE>';
    for(var k in CombatOptions.research[side]){
      m += '<TR><TD>'+unsafeWindow.techcost[k][0]+':</td><td><input id="pbcombat_'+k+'" /></td></tr>';
    }
    m += '<TR><TD>Knight Combat:</td><td><input id="pbcombat_knt" value='+ CombatOptions.knt[side] +' /></td></tr>';
    m += '<TR><TD>Guardian: </td><td> \
        <table><tr><td>Type: </td><td>'+ htmlSelector({wood:'Wood',ore:'Ore'},CombatOptions.guardian[side][0],'id=pbcombat_guartype') +'</td></tr><tr>\
        <td>Level: </td><td><input id="pbcombat_guarlvl" value='+ CombatOptions.guardian[side][1] +' size=4 /></td></tr></table>\
        </td></tr>';
    m += '<TR><TD colspan=2><CENTER><button id=pbcombatresearchsave>Save</button></CENTER></td></tr></table></div>';
    t.pop.getMainDiv().innerHTML = m;
    t.pop.centerMe (mainPop.getMainDiv());  
    t.pop.show (true);
    for(var k in CombatOptions.research[side]){
      t.e_saveresearch('pbcombat_'+k, k, side);
    }
    document.getElementById('pbcombat_knt').addEventListener('change',function(){
      CombatOptions.knt[side] = parseInt(document.getElementById('pbcombat_knt').value);
      saveCombatOptions();
    },false);
    document.getElementById('pbcombat_guartype').addEventListener('change',function(){
      CombatOptions.guardian[side][0] = document.getElementById('pbcombat_guartype').value;
      saveCombatOptions();
    },false);
    document.getElementById('pbcombat_guarlvl').addEventListener('change',function(){
      CombatOptions.guardian[side][1] = parseInt(document.getElementById('pbcombat_guarlvl').value);
      saveCombatOptions();
    },false);
    document.getElementById('pbcombatresearchsave').addEventListener('click',t.c_ratio,false);
  },
  
  e_saveresearch : function(checkboxId, optionName, side){
    var t = Tabs.Combat;
    var checkbox = document.getElementById(checkboxId);
    if (CombatOptions.research[side][optionName])
      checkbox.value = CombatOptions.research[side][optionName];
    checkbox.addEventListener ('change', new eventToggle(checkboxId, optionName, side).handler, false);
    function eventToggle (checkboxId, optionName, side){
      this.handler = handler;
      var optName = optionName;
      function handler(event){
      CombatOptions.research[side][optionName] = parseInt(this.value);
      saveCombatOptions();
      }
    }
  },
  
  c_ratio : function (){
    var t = Tabs.Combat;
    for(var k in CombatOptions.ratio[0]){
      var attack = parseFloat(t.c_attack(k,0));
      for(var tr in unsafeWindow.unitcost){
        var defense = parseFloat(t.c_defense(tr,1));
        var life = parseFloat(t.c_life(tr,1));
        var ratio = ((life+defense)/attack);
        CombatOptions.ratio[0][k][tr] = ratio.toFixed(20);
      }
    }
    for(var k in CombatOptions.ratio[1]){
      var attack = parseFloat(t.c_attack(k,1));
      for(var tr in unsafeWindow.unitcost){
        var defense = parseFloat(t.c_defense(tr,0));
        var life = parseFloat(t.c_life(tr,0));
        var ratio = ((life+defense)/attack);
        CombatOptions.ratio[1][k][tr] = ratio.toFixed(20);
      }
    }
  },
  
  e_calculate: function(){
    var t = Tabs.Combat;
    t.round = 0;
    t.total[0] = 0;
    t.total[1] = 0;
    t.range[0] = 0
    t.range[1] = 0;
    t.speed[0] = 0;
    t.speed[1] = 0;
    for(var tr in unsafeWindow.unitcost){
      var name = unsafeWindow.unitcost[tr][0];
      t.troops[0][tr] = parseIntNan(document.getElementById('pbcombatd_'+tr).value);
      t.troops[1][tr] = parseIntNan(document.getElementById('pbcombata_'+tr).value);
      t.total[0] += t.troops[0][tr];
      t.total[1] += t.troops[1][tr];
      t.lost[0][tr] = 0;
      t.lost[1][tr] = 0;
      t.active[0][tr] = 0;
      t.active[1][tr] = 0;
      if(t.troops[0][tr]>0 && parseInt(t.stats[tr][4]) > t.range[0]) t.range[0] = parseInt(t.stats[tr][4]);
      if(t.troops[1][tr]>0 && parseInt(t.stats[tr][4]) > t.range[1]) t.range[1] = parseInt(t.stats[tr][4]);
      if(t.troops[0][tr]>0 && parseInt(t.stats[tr][3]) > t.speed[0]) t.speed[0] = parseInt(t.stats[tr][3]);
      if(t.troops[1][tr]>0 && parseInt(t.stats[tr][3]) > t.speed[1]) t.speed[1] = parseInt(t.stats[tr][3]);
    }
    if(t.range[1]>t.range[0]){
      t.start = 1; //Attacker starts first if range is longer than defender
      t.range[2] = t.range[1];
    } else {
      t.start = 0;
      t.range[2] = t.range[0];
    }
    for(var tr in unsafeWindow.unitcost){
      if(t.troops[0][tr]>0)
        t.distance[0][tr] = parseInt(t.range[2]/((t.speed[1]/t.speed[0])+1));
      else
        t.distance[0][tr] = 0;
      if(t.troops[1][tr]>0)
        t.distance[1][tr] = parseInt(t.range[2]/((t.speed[0]/t.speed[1])+1));
      else
        t.distance[1][tr] = 0;
    }
    t.c_rounds();
  },
  
  c_rounds: function(){
    var t = Tabs.Combat;
    if(t.total[0]<1 || t.total[1]<1 || t.round>99){
      t.print();
      return;
    }
    t.round++;
    if(t.round>1){
      for(var tr in t.distance[0]){
        t.distance[0][tr] -= t.stats[tr][3];
        if(t.distance[0][tr] < 1) t.distance[0][tr] = 0;
      }
      for(var tr in t.distance[1]){
        t.distance[1][tr] -= t.stats[tr][3];
        if(t.distance[1][tr] < 1) t.distance[1][tr] = 0;
      }
    }
    t.c_remainder();
  },
  
  c_remainder: function(){  //  Life, Attack, Defense, Speed, Range, Load
    var t = Tabs.Combat;
    for(var tr in t.troops[0]){ //Only troops in range are counted
      if(t.stats[tr][4] >= (t.distance[0][tr]))
        t.active[0][tr] = t.troops[0][tr];
    }
    for(var tr in t.troops[1]){
      if(t.stats[tr][4] >= (t.distance[1][tr]))
        t.active[1][tr] = t.troops[1][tr];
    }
    //Defender
    for(var tr in t.active[0]){
      if(t.active[0][tr] < 1) continue;
      var range = t.stats[tr][4] - t.distance[0][tr];
      var count = 0;
      var type = 0;
      if(tr == 'unt6' || tr == 'unt10' || tr == 'unt12') type = 1;
      // GM_log('side0 '+type);
      while(t.active[0][tr] > 0 && count<t.priority[type].length){
        var trr = 'unt'+t.priority[type][count];
        if((t.troops[1][trr] < 1) || (range < t.distance[1][trr])){
          count++;
          continue;
        }
        if(parseInt(CombatOptions.ratio[0][tr][trr]) < 1){
          if(t.active[0][tr] > t.troops[1][trr]){
            t.active[0][tr] -= t.troops[1][trr];
            t.lost[1][trr] += t.troops[1][trr];
            t.total[1] -= t.troops[1][trr];
            t.troops[1][trr] = 0;
          }else {
            t.lost[1][trr] += t.active[0][tr];
            t.total[1] -= t.active[0][tr];
            t.troops[1][trr] -= t.active[0][tr];
            t.active[0][tr] = 0;
          }
        } else {
          var killed = parseInt(t.active[0][tr]/CombatOptions.ratio[0][tr][trr]);
          if(killed > t.troops[1][trr]){
            t.lost[1][trr] += t.troops[1][trr];
            t.total[1] -= t.troops[1][trr];
            t.active[0][tr] -= parseInt(CombatOptions.ratio[0][tr][trr]* t.troops[1][trr]);
            t.troops[1][trr] = 0;
          } else {
            t.lost[1][trr] += killed;
            t.total[1] -= killed;
            t.troops[1][trr] -= killed;
            t.active[0][tr] = 0;
          }
        }
        count++;
      }
    }
    
    //Attacker
    for(var tr in t.active[1]){
      if(t.active[1][tr] < 1) continue;
      var range = t.stats[tr][4] - t.distance[1][tr];
      var count = 0;
      var type = 0;
      if(tr == 'unt6' || tr == 'unt10' || tr == 'unt12') type = 1;
      // GM_log('side1 '+type);
      while(t.active[1][tr] > 0 && count<t.priority[type].length){
        var trr = 'unt'+t.priority[type][count];
        if((t.troops[0][trr] < 1) || (range < t.distance[0][trr])){
          count++;
          continue;
        }
        if(parseInt(CombatOptions.ratio[1][tr][trr]) < 1){
          if(t.active[1][tr] > t.troops[0][trr]){
            t.active[1][tr] -= t.troops[0][trr];
            t.lost[0][trr] += t.troops[0][trr];
            t.total[0] -= t.troops[0][trr];
            t.troops[0][trr] = 0;
          }else {
            t.lost[0][trr] += t.active[1][tr];
            t.total[0] -= t.active[1][tr];
            t.troops[0][trr] -= t.active[1][tr];
            t.active[1][tr] = 0;
          }
        } else {
          var killed = parseInt(t.active[1][tr]/CombatOptions.ratio[1][tr][trr]);
          if(killed > t.troops[0][trr]){
            t.lost[0][trr] += t.troops[0][trr];
            t.total[0] -= t.troops[0][trr];
            t.active[1][tr] -= parseInt(CombatOptions.ratio[1][tr][trr]* t.troops[0][trr]);
            t.troops[0][trr] = 0;
          } else {
            t.lost[0][trr] += killed;
            t.total[0] -= killed;
            t.troops[0][trr] -= killed;
            t.active[1][tr] = 0;
          }
        }
        count++;
      }
    }
    t.c_rounds();
  },
  
  c_attack: function(tr,side){
    var t = Tabs.Combat;
    var att = t.stats[tr][1];
    if(CombatOptions.research[side].tch8) //Add Poison Edge
      att += t.stats[tr][1]*parseFloat(CombatOptions.research[side].tch8*5/100);
    if(CombatOptions.guardian[side][0] == 'ore' && side == 1){ //Add Guardian Boost
      var boost = 0;
      switch(CombatOptions.guardian[side][1]){
        case 1:
          boost = 0.02;
          break;
        case 2:
          boost = 0.04;
          break;
        case 3:
          boost = 0.06;
          break;
        case 4:
          boost = 0.08;
          break;
        case 5:
          boost = 0.12;
          break;
        case 6:
          boost = 0.16;
          break;
        case 7:
          boost = 0.20;
          break;
        case 8:
          boost = 0.26;
          break;
        case 9:
          boost = 0.32;
          break;
        case 10:
          boost = 0.40;
          break;
        default:
          boost = 0;
      }
      att += t.stats[tr][1]*boost;
    }
    if(CombatOptions.knt[side]) //Add knight boost
      att += t.stats[tr][1]*parseFloat((CombatOptions.knt[side]/2)/100);
    // logit('side'+side+' '+tr+' att'+att);
    return att;
  },
  c_defense: function(tr,side){
    var t = Tabs.Combat;
    var def = t.stats[tr][2];
    if(CombatOptions.research[side].tch9) //Add Metal Alloy
      def += t.stats[tr][2]*parseFloat(CombatOptions.research[side].tch9*5/100);
    if(CombatOptions.knt[side]) //Add knight boost
      def += t.stats[tr][2]*parseFloat((CombatOptions.knt[side]/2)/100);
    // logit('side'+side+' '+tr+' def'+def);
    return def;
  },
  c_life: function(tr,side){
    var t = Tabs.Combat;
    var life = t.stats[tr][0];
    if(CombatOptions.research[side].tch15) //Add Healing Potions
      life += t.stats[tr][0]*parseFloat(CombatOptions.research[side].tch15*5/100);
    if(CombatOptions.guardian[side][0] == 'wood' && side == 0){ //Add Guardian Boost
      var boost = 0;
      switch(CombatOptions.guardian[side][1]){
        case 1:
          boost = 0.01;
          break;
        case 2:
          boost = 0.02;
          break;
        case 3:
          boost = 0.03;
          break;
        case 4:
          boost = 0.04;
          break;
        case 5:
          boost = 0.06;
          break;
        case 6:
          boost = 0.08;
          break;
        case 7:
          boost = 0.10;
          break;
        case 8:
          boost = 0.13;
          break;
        case 9:
          boost = 0.16;
          break;
        case 10:
          boost = 0.20;
          break;
        default:
          boost = 0;
      }
      life += t.stats[tr][0]*boost;
    }
    // logit('side'+side+' '+tr+' life'+life);
    return life;
  },
  
  print: function (){
    var t = Tabs.Combat;
    var m = '<div class=pbStat>Results</div><table><TR><TD colspan=3><b>Attacking</b></td><TD colspan=3><b>Defending</b></td><TD>Rounds :'+t.round+'</td></TR>';
    for(var tr in unsafeWindow.unitcost){
      var name = unsafeWindow.unitcost[tr][0];
      m+='<tr><td>'+name+' :</td><td>'+ t.troops[1][tr] +'</td><td><span class=boldRed>'+ t.lost[1][tr] +'</span></td><td>'+name+' :</td><td>'+ t.troops[0][tr] +'</td><td><span class=boldRed>'+ t.lost[0][tr] +'</span></td></tr>';
    }
    m+='</table>';
    document.getElementById('pbcombat_rslt').innerHTML = m;
  },
  show: function(){
  
  },
  
  hide: function(){
  
  },
}


Tabs.startup = {
    tabOrder : 99999,
    tabDisabled : false,
    tabLabel : 'StartUp',
    myDiv : null,
    where: 'City', //Initialize to city by default


    init : function (div){
        var t = Tabs.startup;
        t.myDiv= div;
        var counter=0;
        var m = '<DIV id=pbStartupDiv class=pbStat>New Domain Tools</div><TABLE id=pbNewDomain width=100% height=0% class=pbTab><TR align="center">';
        m += '<DIV id=pblvlcity align=center></div><DIv><INPUT id=addToBuildQueue type=submit value="Add to build queue"></div>';
        m += '<INPUT id=toggleFieldLayout type=submit value="Show Field Layout"><INPUT id=toggleCityLayout type=submit value="Show City Layout"><INPUT id=hideGrids type=submit value="Hide Layouts">';
        m += '<DIV id=mainTitles></div>';    
        m += '<DIV id=gridPicture></div>';
           m += '<DIV id=layoutBoxes></div>';
          
        t.myDiv.innerHTML = m;
        t.city = new CdispCityPicker ('pblvlcity', document.getElementById('pblvlcity'), true, t.ClickCitySelect, 0);

        /*
        document.getElementById('test').addEventListener('click', function () {
                Options.lvl5FarmDone = "false";
                Options.lvl3MineDone = "false";
                Options.lvl2BarracksDone = "false";
                Options.lvl3WallDone = "false";
                Options.lvl5CastleDone = "false";
                Options.lvl2WorkshopDone = "false";
                saveOptions();
        });*/
      

        document.getElementById('toggleFieldLayout').addEventListener('click', function () {
                t.paintFieldGrid();
        });
        document.getElementById('toggleCityLayout').addEventListener('click', function () {
                t.paintCityGrid();
        });
        document.getElementById('hideGrids').addEventListener('click', function () {
                document.getElementById('mainTitles').innerHTML = "";
                document.getElementById('gridPicture').innerHTML = "";
                document.getElementById('layoutBoxes').innerHTML = "";

        });
        document.getElementById('addToBuildQueue').addEventListener('click', function () {
            if (t.where == "City") t.addCityToQueue();
            if (t.where == "Field") t.addFieldToQueue();
        });
    },
    ClickCitySelect : function(){ //Call this function when users switch to another city
        var t = Tabs.startup;
        switch(t.where){
            case 'City':
                t.paintCityGrid();
                break;
            case 'Field':
                t.paintFieldGrid();
                break;
            default : //If somehow something goes wrong then paint city view by default
                t.paintCityGrid();
                break;
        }
    },
    getCastleLevel:function(){
        var t = Tabs.startup
    var castle = Seed.buildings["city" + t.city.city.id]["pos0"][1];
        switch(castle){
                case "1":fields = 13;break;
                case "2":fields = 16;break;
                case "3":fields = 19;break;
                case "4":fields = 22;break;
                case "5":fields = 25;break;
                case "6":fields = 28;break;
                case "7":fields = 31;break;
                case "8":fields = 34;break;
                case "9":fields = 37;break;
                case "10":fields = 40;break;
                case "11":fields = 41;break;
                case "12":fields = 42;break;
        }
        max = (fields-1) + 100;
        return(max)
    },

    addCityToQueue:function(){
        var t = Tabs.startup;
            for (pos=1;pos<=32;pos++){
                      if  (buildingIDs[document.getElementById('tileID' + pos).value] >0) {
                          if (Seed.buildings['city' + t.city.city.id]["pos" + pos] == undefined){
                        var buildingMode = "build";
                        var cityId =  t.city.city.id;
                        var buildingPos = pos;
                        var buildingType = buildingIDs[document.getElementById('tileID' + pos).value];
                        var buildingLevel = 0;
                        var buildingAttempts = 0;
                        var result = Tabs.build.calculateQueueValues(cityId, buildingLevel, buildingType, buildingMode);
                        var buildingMult = result[0];
                        var buildingTime = result[1];
                        var buildingId = buildingIDs[document.getElementById('tileID' + pos).value];
                        Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode);  
                        }                  
                    }
            }
    },  
    buildExtraLevels:function(rslt,buildItem){
        logit('lvl5FarmDone = ' + Options.lvl5FarmDone + ' lvl3MineDone = ' + Options.lvl3MineDone + ' lvl2BarracksDone = ' + Options.lvl2BarracksDone + ' lvl3WallDone = ' + Options.lvl3WallDone + ' lvl2WorkshopDone = ' + Options.lvl2WorkshopDone + ' lvl5CastleDone = ' + Options.lvl5CastleDone + ' buildingType =' + buildItem.buildingType)
        if (Options.lvl5FarmDone == "false" && buildItem.buildingType == "1") {
            var buildingMode = "build"
               var cityId = buildItem.cityId
               var time = parseInt(buildItem.buildingTime);
            var mult = parseInt(buildItem.buildingMult);
            var attempt = parseInt(buildItem.buildingAttempt);
            var buildingPos   = parseInt(buildItem.buildingPos);
            var buildingType  = 1;
            var buildingLevel = 1; //parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
            var buildingId    = rslt.buildingId;
            var buildingAttempts = 0;
            for (var bL = 1; bL <5; bL++) {
                var queueId = Tabs.build.loaded_bQ.length;
                var result = Tabs.build.calculateQueueValues(cityId, bL, buildingType, buildingMode);
                var buildingMult = result[0];
                var buildingTime = result[1];
                queueId = queueId ;
                Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult,buildingMode);
                Tabs.build._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
               }
               Options.lvl5FarmDone = "true";
               saveOptions();
        }
        if (Options.lvl3MineDone == "false" && buildItem.buildingType == "4") {
            var buildingMode = "build"
               var cityId = buildItem.cityId
               var time = parseInt(buildItem.buildingTime);
            var mult = parseInt(buildItem.buildingMult);
            var attempt = parseInt(buildItem.buildingAttempt);
            var buildingPos   = parseInt(buildItem.buildingPos);
            var buildingType  = 4;
            var buildingLevel = 1; //parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
            var buildingId    = rslt.buildingId;
            var buildingAttempts = 0;
            for (var bL = 1; bL <3; bL++) {
                var queueId = Tabs.build.loaded_bQ.length;
                var result = Tabs.build.calculateQueueValues(cityId, bL, buildingType, buildingMode);
                var buildingMult = result[0];
                var buildingTime = result[1];
                queueId = queueId ;
                Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult,buildingMode);
                Tabs.build._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
               }
               Options.lvl3MineDone = "true";
               saveOptions();
        }
        if (Options.lvl2BarracksDone == "false" && buildItem.buildingType == "13") {
            var buildingMode = "build"
               var cityId = buildItem.cityId
               var time = parseInt(buildItem.buildingTime);
            var mult = parseInt(buildItem.buildingMult);
            var attempt = parseInt(buildItem.buildingAttempt);
            var buildingPos   = parseInt(buildItem.buildingPos);
            var buildingType  = 13;
            var buildingLevel = 1; //parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
            var buildingId    = rslt.buildingId;
            var buildingAttempts = 0;
            for (var bL = 1; bL <2; bL++) {
                var queueId = Tabs.build.loaded_bQ.length;
                var result = Tabs.build.calculateQueueValues(cityId, bL, buildingType, buildingMode);
                var buildingMult = result[0];
                var buildingTime = result[1];
                queueId = queueId ;
                Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult,buildingMode);
                Tabs.build._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
               }
               Options.lvl2BarracksDone = "true";
               saveOptions();
        }
        if (Options.lvl3WallDone == "false" && buildItem.buildingType == "19") { //WALL
            var buildingMode = "build"
               var cityId = buildItem.cityId
               var time = parseInt(buildItem.buildingTime);
            var mult = parseInt(buildItem.buildingMult);
            var attempt = parseInt(buildItem.buildingAttempt);
            var buildingPos   = parseInt(buildItem.buildingPos);
            var buildingType  = 19;
            var buildingLevel = 1;
            var buildingId    = rslt.buildingId;
            var buildingAttempts = 0;
            for (var bL = 1; bL <3; bL++) {
                var queueId = Tabs.build.loaded_bQ.length;
                var result = Tabs.build.calculateQueueValues(cityId, bL, buildingType, buildingMode);
                var buildingMult = result[0];
                var buildingTime = result[1];
                queueId = queueId ;
                Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult,buildingMode);
                Tabs.build._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
               }
               Options.lvl3WallDone = "true";
               saveOptions();
        }
        if (Options.lvl2WorkshopDone == "false" && buildItem.buildingType == "16") { //workshop
            var buildingMode = "build"
               var cityId = buildItem.cityId
               var time = parseInt(buildItem.buildingTime);
            var mult = parseInt(buildItem.buildingMult);
            var attempt = parseInt(buildItem.buildingAttempt);
            var buildingPos   = parseInt(buildItem.buildingPos);
            var buildingType  = 16;
            var buildingLevel = 1; //parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
            var buildingId    = rslt.buildingId;
            var buildingAttempts = 0;
            for (var bL = 1; bL <=2; bL++) {
                var queueId = Tabs.build.loaded_bQ.length;
                var result = Tabs.build.calculateQueueValues(cityId, bL, buildingType, buildingMode);
                var buildingMult = result[0];
                var buildingTime = result[1];
                queueId = queueId ;
                Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult,buildingMode);
                Tabs.build._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
               }
               Options.lvl2WorkshopDone = "true";
               saveOptions();
        }
        /*if (Options.lvl5CastleDone == "false" && buildItem.buildingType == "") {
            var buildingMode = "build"
               var cityId = buildItem.cityId
               var time = parseInt(buildItem.buildingTime);
            var mult = parseInt(buildItem.buildingMult);
            var attempt = parseInt(buildItem.buildingAttempt);
            var buildingPos   = parseInt(buildItem.buildingPos);
            var buildingType  = //;
            var buildingLevel = 1; //parseInt(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
            var buildingId    = Seed.buildings["city" + cityId]["pos0"][3]
            var buildingAttempts = 0;
            for (var bL = 1; bL <5; bL++) {
                var queueId = Tabs.build.loaded_bQ.length;
                var result = Tabs.build.calculateQueueValues(cityId, bL, buildingType, buildingMode);
                var buildingMult = result[0];
                var buildingTime = result[1];
                queueId = queueId ;
                Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, bL, buildingAttempts, buildingMult,buildingMode);
                Tabs.build._addTab(queueId, cityId, buildingType, buildingTime, bL, buildingAttempts, buildingMode);
               }
               Options.lvl2BarracksDone = "true";
               saveOptions();
        }*/

    },

    addFieldToQueue:function(){
        var t = Tabs.startup;
        var max = t.getCastleLevel();
        Options.lvl5FarmDone = "false"
        //var skipMain = false;
        //1=5
        //4=3
        //lvl5FarmDone: "false",
          //lvl3MineDone: "false",
            for (pos=100;pos<=max;pos++){
                    if  (buildingIDs[document.getElementById('tileID' + pos).value] >0) {
                        if (Seed.buildings['city' + t.city.city.id]["pos" + pos] == undefined){
                        var buildingMode = "build";
                        var cityId =  t.city.city.id;
                        var buildingPos = pos;
                        var buildingType = buildingIDs[document.getElementById('tileID' + pos).value];
                        var buildingLevel = 0;
                        var buildingAttempts = 0;
                        var result = Tabs.build.calculateQueueValues(cityId, buildingLevel, buildingType, buildingMode);
                        var buildingMult = result[0];
                        var buildingTime = result[1];
                        var buildingId = buildingIDs[document.getElementById('tileID' + pos).value];
                        Tabs.build.addQueueItem(cityId, buildingPos, buildingType, buildingId, buildingTime, buildingLevel, buildingAttempts, buildingMult, buildingMode);                      
                        }
                }
            }
    },  

    paintCityGrid:function(cityDiv){
        var t = Tabs.startup;
        t.myDiv = cityDiv;
        t.where = "City";
        var counter = 0;
  var AscCityInd = Seed.cityData.city[t.city.city.id].isPrestigeCity;
        var cityGrid = '<img src="http://koc-power-bot.googlecode.com/svn/trunk/CityTileIDs.jpg">';
  var asccityGrid = '<img src="http://koc-power-bot.googlecode.com/svn/trunk/AscCityTileIDs.jpg">';
        document.getElementById('gridPicture').innerHTML = "";
  if(AscCityInd == true) {
    document.getElementById('gridPicture').innerHTML = asccityGrid;
  } else {
    document.getElementById('gridPicture').innerHTML = cityGrid;
  }
        var message='<TABLE id=pbLayoutBoxes width=100% height=0%><INPUT id=showDefaults type=submit value="Load Defaults"><INPUT id=loadAscended1 type=submit value="Load Ascended Defaults"><INPUT id=loadAscended2 type=submit value="Load Ascend Quick Defaults"><INPUT id=setDefaults type=submit value="Set Defaults">';

        for (k=1;k<=32;k++){
            if (k==1){
                counter++
                message += '<TD>Tile1<SELECT id=tileID1><OPTION value="Wall">Wall</option>'
            }else{
            counter++;
            message += '<TD>Tile'+k+'<SELECT id=tileID'+k+'><OPTION value="Nothing">---Select---</option>'
                  for (kk in cityBuildingNames){
                      message += '<OPTION value='+kk+'>'+cityBuildingNames[kk]+'</option>';
                }
            message += '</options>';
        if (counter % 4 == 0)message+='</tr>';
        }
        }
        document.getElementById('layoutBoxes').innerHTML = message;
            for (pos=1;pos<=32;pos++){
                if (Seed.buildings['city' + t.city.city.id]["pos" + pos] != undefined){
                    document.getElementById('tileID' + pos).value = buildingTypes["type"+Seed.buildings['city' +t.city.city.id]["pos"+pos][0]];
                    document.getElementById('tileID' + pos).disabled = true;
                    logit("POS = " + pos + ' ' + buildingTypes["type"+Seed.buildings['city' +t.city.city.id]["pos"+pos][0]] + ' TYPE = ' + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]);
                }
            }
       
        jQuery('#loadAscended1').click(function()
        {
          for (pos = 1 ; pos <= 32 ; pos++)
          {
            layoutOptions['pos' +pos] = ascendedLayout1Options['pos' +pos];

            if (Seed.buildings['city' + t.city.city.id]["pos" + pos] == undefined)
            {
              document.getElementById('tileID' + pos).value = layoutOptions['pos' +pos];
            }
            else
            {
              document.getElementById('tileID' + pos).value = unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0];
              document.getElementById('tileID' + pos).disabled = true;
            }
          }

          saveLayoutOptions();
        });

        jQuery('#loadAscended2').click(function()
        {
          for (pos = 1 ; pos <= 32 ; pos++)
          {
            layoutOptions['pos' +pos] = ascendedLayout2Options['pos' +pos];

            if (Seed.buildings['city' + t.city.city.id]["pos" + pos] == undefined)
            {
              document.getElementById('tileID' + pos).value = layoutOptions['pos' +pos];
            }
            else
            {
              document.getElementById('tileID' + pos).value = unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0];
              document.getElementById('tileID' + pos).disabled = true;
            }
          }

          saveLayoutOptions();
        });

        document.getElementById('showDefaults').addEventListener('click', function(){
            for (pos=1;pos<=32;pos++){
                //logit(document.getElementById('tileID' + i).value)
                if (Seed.buildings['city' + t.city.city.id]["pos" + pos] == undefined){
                    document.getElementById('tileID' + pos).value = layoutOptions['pos' +pos];
                }else{
                    //logit(unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0]);

                    document.getElementById('tileID' + pos).value = unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0];
                    document.getElementById('tileID' + pos).disabled = true;
                }
               }
        });
        document.getElementById('setDefaults').addEventListener('click', function(){
            for (pos=1;pos<=32;pos++){
                layoutOptions['pos'+pos] = document.getElementById('tileID' + pos).value

            }
            saveLayoutOptions();
        });
        //code for set buttons
    },


    paintFieldGrid:function(fieldsDiv){
        var t = Tabs.startup;
        t.myDiv = fieldsDiv;
        t.where = "Field";
        var counter = 0;
        var fields = 13;
        var max = t.getCastleLevel();
        var fieldGrid = '<img src="http://koc-power-bot.googlecode.com/svn/trunk/FieldsTileIDs.jpg">';
        document.getElementById('gridPicture').innerHTML = "";
        document.getElementById('gridPicture').innerHTML = fieldGrid;
        var mess='<TABLE id=pbLayoutBoxes width=100% height=0%><INPUT id=showFieldDefaults type=submit value="Load Defaults"><INPUT id=setFieldDefaults type=submit value="Set Defaults">';
        for (k=100;k<=max;k++){
            if (k != 140 && k != 141){
                counter++
                mess += '<TD>Tile'+k+'<SELECT id=tileID'+k+'><OPTION value="Nothing">---Select---</option>'
                      for (kk in fieldBuildingNames){
                          mess += '<OPTION value='+kk+'>'+ fieldBuildingNames[kk]+'</option>';
                    }
                mess += '</options>';
            if (counter % 4 == 0)mess+='<tr>';
            }
        }
        document.getElementById('layoutBoxes').innerHTML = mess;
        for (pos=100;pos<=max;pos++){
                if (Seed.buildings['city' + t.city.city.id]["pos" + pos] != undefined){
                    document.getElementById('tileID' + pos).value = unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0];
                    document.getElementById('tileID' + pos).disabled = true;
                }
            }
  
    document.getElementById('showFieldDefaults').addEventListener('click', function(){
            for (pos=100;pos<=max;pos++){
                //logit(document.getElementById('tileID' + i).value)
                if (Seed.buildings['city' + t.city.city.id]["pos" + pos] == undefined){
                    document.getElementById('tileID' + pos).value = fieldlayoutOptions['pos' +pos];
                }else{
                    //logit(unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0]);
                    //logit(unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0])
                    document.getElementById('tileID' + pos).value = unsafeWindow.buildingcost["bdg" + Seed.buildings['city' +t.city.city.id]["pos"+pos][0]][0];
                    document.getElementById('tileID' + pos).disabled = true;
                }
               }
    });
    document.getElementById('setFieldDefaults').addEventListener('click', function(){
            for (pos=100;pos<=max;pos++){
                fieldlayoutOptions['pos'+pos] = document.getElementById('tileID' + pos).value;
            }
            savefieldlayoutOptions();
    });
    },
  
  
    show : function(){},
    hide : function(){},
} 




/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: Crest
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.Crest = 
{
  tabOrder : 70,
  myDiv : null,
  error_code: 0,
  pendingCrest : 0,
  knt:{},
  knightCount: 0,

/** window display **/   
  init : function (div)
  {
    var t = Tabs.Crest;
    Options.crestMarchError = 0;

    setInterval(t.sendCrestReport, 1*60*1000);  
    t.timer = setTimeout(function(){ t.Rounds(1,0,0);}, Options.Crestinterval * 1000);

    t.myDiv = div;
    var selbut=0;
    var m = '';
    m += '<DIV id=pbTowrtDivF class=pbStat>AUTOMATED CRESTING FUNCTION</div>';
    m += '<TABLE id=pbcrestfunctions width=100% height=0% class=pbTab><TR align="center">';
    if (Options.crestRunning == false) 
    {
      m += '<TD><INPUT id=Cresttoggle type=submit value="Crest = OFF"></td>';
    } else {
      m += '<TD><INPUT id=Cresttoggle type=submit value="Crest = ON"></td>';
    }



    m += '<TD><INPUT id=CrestHelp type=submit value="HELP"></td>';
    m += '<td><INPUT id=showCrestTargets type=submit value="Show Targets"></td>';
    m += '<TD><INPUT id=pbsendreport type=checkbox '+ (Options.crestreport?' CHECKED':'') +'\> Send Crest report every ';
    m += '<INPUT id=pbsendcrestreportint value='+ Options.CrestMsgInterval +' type=text size=3 \> hours </td>\
      <TD>Attack interval <INPUT type=text size=3 value='+Options.Crestinterval+' id=pbcrest_interval />seconds</TD></TR>';
    m += '<TR>';
    m += '<TD colspan=4><div id=pbMarchStatus></div></TD>';
    m += '<td>Leave rally slots free <input type=text size=3 value='+Options.CrestFreeSlots+' id=pbcrest_freeslots /></td>';
    m += '</tr>';
    
    if(EnableOptions)
    {
      m += '<tr>';
      m += '<td colspan=3><INPUT id=pbStopCrestOnChange type=checkbox '+ (Options.stopCrestOnChanges?' CHECKED':'') +'\> Stop crest on troop losses</td>';
      m += '<td colspan=2>Troop loss threshold <INPUT type=text size=6 value='+ Options.crestLossThreshold +' id=pbCrestLossThreshold /></td>';
      m += '</tr>';
    }
    
    m += '</table>';
  
    m += '<DIV id=pbOpt class=pbStat>CRESTING OPTIONS</div><TABLE id=pbcrestopt   width=100% height=0% class=pbTab><TR align="center"></TR></table>';
    m += '<DIV style="margin-bottom:10px;">Crest from city: <span id=crestcity></span></div>';
    
    m += '<TABLE class=ptTab><TR><TD>Wild coords: X:<INPUT id=pbcrestx type=text size=3 maxlength=3 value=""></td>';
    m += '<TD>Y:<INPUT id=pbcresty type=text size=3 maxlength=3 value=""></td></tr>';
    m += '<TR><TD><INPUT type=checkbox id=pbcrest_iswild CHECKED /> Is Wild </td></tr></table>';
   
    m += '<TABLE class=ptTab><TR><TD><INPUT type=checkbox id=pbcrest_rnd1 CHECKED /></td><TD>Wave <b>1</b>: </td><TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_30.png></td><TD><INPUT id=R1ST type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_30.png></td><TD><INPUT id=R1MM type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_30.png></td><TD><INPUT id=R1Scout type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_30.png></td><TD><INPUT id=R1Pike type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_30.png></td><TD><INPUT id=R1Sword type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_30.png></td><TD><INPUT id=R1Arch type=text size=7 maxlength=6 value=0></td></tr>';
    m += '<tr><td></td><td></td><TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_30.png></td><TD><INPUT id=R1LC type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_30.png></td><TD><INPUT id=R1HC type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_30.png></td><TD><INPUT id=R1SW type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_30.png></td><TD><INPUT id=R1Ball type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_30.png></td><TD><INPUT id=R1Ram type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_30.png></td><TD><INPUT id=R1Cat type=text size=7 maxlength=6 value=0></td></tr><tr><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td></tr>';
    
    m += '<TR><TD><INPUT type=checkbox id=pbcrest_rnd2 CHECKED /></td><TD>Wave <b>2</b>: </td><TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_1_30.png></td><TD><INPUT id=R2ST type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_2_30.png></td><TD><INPUT id=R2MM type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_3_30.png></td><TD><INPUT id=R2Scout type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_4_30.png></td><TD><INPUT id=R2Pike type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_5_30.png></td><TD><INPUT id=R2Sword type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_30.png></td><TD><INPUT id=R2Arch type=text size=7 maxlength=6 value=0></td></tr>';
    m += '<tr><td></td><td></td><TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_7_30.png></td><TD><INPUT id=R2LC type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_8_30.png></td><TD><INPUT id=R2HC type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_9_30.png></td><TD><INPUT id=R2SW type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_10_30.png></td><TD><INPUT id=R2Ball type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_11_30.png></td><TD><INPUT id=R2Ram type=text size=7 maxlength=6 value=0></td>';
    m += '<TD>&nbsp;&nbsp;<img src=http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_12_30.png></td><TD><INPUT id=R2Cat type=text size=7 maxlength=6 value=0></td></tr></table>';
    m += '<DIV style="text-align:center; margin-top:15px"><INPUT id=pbSaveRouteCrest type=submit value="Add Attack"></div>';
    
    t.myDiv.innerHTML = m;
  
    document.getElementById('pbsendreport').addEventListener('change', function(){
      Options.crestreport = document.getElementById('pbsendreport').checked;
      saveOptions();
    }, false);
    document.getElementById('pbsendcrestreportint').addEventListener('change', function(){
      Options.CrestMsgInterval = parseInt(document.getElementById('pbsendcrestreportint').value);
      saveOptions();
    }, false);
    $("pbcrest_interval").addEventListener('change', function(e){
      Options.Crestinterval = parseIntNan(e.target.value);
      saveOptions();
    },false);
    if(EnableOptions)
    {
      $("pbCrestLossThreshold").addEventListener('change', function(e){
        Options.crestLossThreshold = parseIntWithDefault(e.target.value, 1);
        saveOptions();
      },false);
    }
    $("pbcrest_freeslots").addEventListener('change', function(e){
      Options.CrestFreeSlots = parseIntNan(e.target.value);
      saveOptions();
    },false);
      for (var i=0;i<Seed.cities.length;i++){
      if (CrestOptions.CrestCity == Seed.cities[i][0]){
        selbut=i;
        break;
      }
    }
      
    t.tcp = new CdispCityPicker ('crestcityselect', document.getElementById('crestcity'), true, t.clickCitySelect, selbut);
    
    if (CrestOptions.CrestCity == 0) {
      CrestOptions.CrestCity = t.tcp.city.id
    }

  $('pbcrest_iswild').addEventListener('click', function(){
    CrestOptions.isWild = this.checked;
  },false);
  $('pbcrest_rnd1').addEventListener('click', function(){
    var checked = (!this.checked);
    CrestOptions.round1 = this.checked;
    $('R1ST').disabled = checked;
    $('R1MM').disabled = checked;
    $('R1Scout').disabled = checked;
    $('R1Pike').disabled = checked;
    $('R1Sword').disabled = checked;
    $('R1Arch').disabled = checked;
    $('R1LC').disabled = checked;
    $('R1HC').disabled = checked;
    $('R1SW').disabled = checked;
    $('R1Ball').disabled = checked;
    $('R1Ram').disabled = checked;
    $('R1Cat').disabled = checked;
  },false);
  $('pbcrest_rnd2').addEventListener('click', function(){
    var checked = (!this.checked);
    CrestOptions.round2 = this.checked;
    $('R2ST').disabled = checked;
    $('R2MM').disabled = checked;
    $('R2Scout').disabled = checked;
    $('R2Pike').disabled = checked;
    $('R2Sword').disabled = checked;
    $('R2Arch').disabled = checked;
    $('R2LC').disabled = checked;
    $('R2HC').disabled = checked;
    $('R2SW').disabled = checked;
    $('R2Ball').disabled = checked;
    $('R2Ram').disabled = checked;
    $('R2Cat').disabled = checked;
  },false);
      document.getElementById('pbcrestx').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('pbcrestx').value)) document.getElementById('pbcrestx').value='' ;
      }, false);

      document.getElementById('pbcresty').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('pbcresty').value)) document.getElementById('pbcresty').value='' ;
      }, false);

      document.getElementById('R1ST').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1ST').value)) document.getElementById('R1ST').value=0 ;
      }, false);

      document.getElementById('R1MM').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1MM').value)) document.getElementById('R1MM').value=0 ;
      }, false);

      document.getElementById('R1Pike').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Pike').value)) document.getElementById('R1Pike').value=0 ;
      }, false);

      document.getElementById('R1Scout').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Scout').value)) document.getElementById('R1Scout').value=0 ;
      }, false);

      document.getElementById('R1Sword').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Sword').value)) document.getElementById('R1Sword').value=0 ;
      }, false);

      document.getElementById('R1Arch').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Arch').value)) document.getElementById('R1Arch').value=0 ;
      }, false);

      document.getElementById('R1LC').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1LC').value)) document.getElementById('R1LC').value=0 ;
      }, false);

      document.getElementById('R1HC').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1HC').value)) document.getElementById('R1HC').value=0 ;
      }, false);

      document.getElementById('R1SW').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1SW').value)) document.getElementById('R1SW').value=0 ;
      }, false);

      document.getElementById('R1Ball').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Ball').value)) document.getElementById('R1Ball').value=0 ;
      }, false);

      document.getElementById('R1Ram').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Ram').value)) document.getElementById('R1Ram').value=0 ;
      }, false);

      document.getElementById('R1Cat').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R1Cat').value)) document.getElementById('R1Cat').value=0 ;
      }, false);
    
      document.getElementById('R2ST').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2ST').value)) document.getElementById('R2ST').value=0 ;
      }, false);

      document.getElementById('R2MM').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2MM').value)) document.getElementById('R2MM').value=0 ;
      }, false);

      document.getElementById('R2Pike').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Pike').value)) document.getElementById('R2Pike').value=0 ;
      }, false);

      document.getElementById('R2Scout').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Scout').value)) document.getElementById('R2Scout').value=0 ;
      }, false);

      document.getElementById('R2Sword').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Sword').value)) document.getElementById('R2Sword').value=0 ;
      }, false);

      document.getElementById('R2Arch').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Arch').value)) document.getElementById('R2Arch').value=0 ;
      }, false);

      document.getElementById('R2LC').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2LC').value)) document.getElementById('R2LC').value=0 ;
      }, false);

      document.getElementById('R2HC').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2HC').value)) document.getElementById('R2HC').value=0 ;
      }, false);

      document.getElementById('R2SW').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2SW').value)) document.getElementById('R2SW').value=0 ;
      }, false);

      document.getElementById('R2Ball').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Ball').value)) document.getElementById('R2Ball').value=0 ;
      }, false);

      document.getElementById('R2Ram').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Ram').value)) document.getElementById('R2Ram').value=0 ;
      }, false);

      document.getElementById('R2Cat').addEventListener('keyup', function(){
          if (isNaN(document.getElementById('R2Cat').value)) document.getElementById('R2Cat').value=0 ;
      }, false);
         
    document.getElementById('crestcity').addEventListener('click', function(){CrestOptions.CrestCity = t.tcp.city.id;} , false);
    document.getElementById('Cresttoggle').addEventListener('click', function(){t.toggleCrestState(this)} , false);
    document.getElementById('pbcrestx').addEventListener('change', function(){CrestOptions.X = document.getElementById('pbcrestx').value;;} , false);
    document.getElementById('pbcresty').addEventListener('change', function(){CrestOptions.Y = document.getElementById('pbcresty').value;} , false);
    document.getElementById('R1ST').addEventListener('change', function(){CrestOptions.R1ST = document.getElementById('R1ST').value;} , false);
    document.getElementById('R1MM').addEventListener('change', function(){CrestOptions.R1MM = document.getElementById('R1MM').value;} , false);
    document.getElementById('R1Scout').addEventListener('change', function(){CrestOptions.R1Scout = document.getElementById('R1Scout').value;} , false);
    document.getElementById('R1Pike').addEventListener('change', function(){CrestOptions.R1Pike = document.getElementById('R1Pike').value;} , false);
    document.getElementById('R1Sword').addEventListener('change', function(){CrestOptions.R1Sword = document.getElementById('R1Sword').value;} , false);
    document.getElementById('R1Arch').addEventListener('change', function(){CrestOptions.R1Arch = document.getElementById('R1Arch').value;} , false);
    document.getElementById('R1LC').addEventListener('change', function(){CrestOptions.R1LC = document.getElementById('R1LC').value;} , false);
    document.getElementById('R1HC').addEventListener('change', function(){CrestOptions.R1HC = document.getElementById('R1HC').value;} , false);
    document.getElementById('R1SW').addEventListener('change', function(){CrestOptions.R1SW = document.getElementById('R1SW').value;} , false);
    document.getElementById('R1Ball').addEventListener('change', function(){CrestOptions.R1Ball = document.getElementById('R1Ball').value;} , false);
    document.getElementById('R1Ram').addEventListener('change', function(){CrestOptions.R1Ram = document.getElementById('R1Ram').value;} , false);
    document.getElementById('R1Cat').addEventListener('change', function(){CrestOptions.R1Cat = document.getElementById('R1Cat').value;} , false);
    document.getElementById('R2ST').addEventListener('change', function(){CrestOptions.R2ST = document.getElementById('R2ST').value;} , false);
    document.getElementById('R2MM').addEventListener('change', function(){CrestOptions.R2MM = document.getElementById('R2MM').value;} , false);
    document.getElementById('R2Scout').addEventListener('change', function(){CrestOptions.R2Scout = document.getElementById('R2Scout').value;} , false);
    document.getElementById('R2Pike').addEventListener('change', function(){CrestOptions.R2Pike = document.getElementById('R2Pike').value;} , false);
    document.getElementById('R2Sword').addEventListener('change', function(){CrestOptions.R2Sword = document.getElementById('R2Sword').value;} , false);
    document.getElementById('R2Arch').addEventListener('change', function(){CrestOptions.R2Arch = document.getElementById('R2Arch').value;} , false);
    document.getElementById('R2LC').addEventListener('change', function(){CrestOptions.R2LC = document.getElementById('R2LC').value;} , false);
    document.getElementById('R2HC').addEventListener('change', function(){CrestOptions.R2HC = document.getElementById('R2HC').value;} , false);
    document.getElementById('R2SW').addEventListener('change', function(){CrestOptions.R2SW = document.getElementById('R2SW').value;} , false);
    document.getElementById('R2Ball').addEventListener('change', function(){CrestOptions.R2Ball = document.getElementById('R2Ball').value;} , false);
    document.getElementById('R2Ram').addEventListener('change', function(){CrestOptions.R2Ram = document.getElementById('R2Ram').value;} , false);
    document.getElementById('R2Cat').addEventListener('change', function(){CrestOptions.R2Cat = document.getElementById('R2Cat').value;} , false);
    document.getElementById('CrestHelp').addEventListener('click', function(){t.helpPop();} , false);
    document.getElementById('pbSaveRouteCrest').addEventListener('click', function(){t.addCrestRoute();}, false);
    document.getElementById('showCrestTargets').addEventListener('click', function(){t.showCrestRoute();}, false);
    
    jQuery('#pbStopCrestOnChange').change( function()
    {
      if (jQuery(this).is(':checked')) 
      {
        Options.stopCrestOnChanges = true;
      }
      else
      {
        Options.stopCrestOnChanges = false;
      }
      
      saveOptions();
    });
    
    setInterval(t.marchStatus, 5 * 1000);
    setInterval(t.checkForChanges, 5 * 1000);
  },
  
  checkForChanges: function()
  {
    if(!Options.stopCrestOnChanges || (Options.crestRunning == false))
    {
      return;
    }
    
    var queue = Seed.queue_atkp;

    for (cityId in queue)
    {
      for(marchId in queue[cityId])
      {
        var march = queue[cityId][marchId];
        
        if(march.marchType == 4 && march.marchStatus == 8 )
        {
          var crestMarch = false;
          
          for(i in CrestData) 
          {
            if(march.toXCoord == CrestData[i].X && march.toYCoord == CrestData[i].Y) 
            {
              crestMarch = true;
            }
          }
          
          if(crestMarch)
          {
            var troopsLost = 0;
            var unitsSent = 0;
            
            for(unit = 0 ; unit <= 12 ; unit++)
            {
              var lost = 0;
              
              lost = parseIntWithDefault(march["unit" + unit + "Count"], 0) - parseIntWithDefault(march["unit" + unit + "Return"], 0)
              unitsSent += parseIntWithDefault(march["unit" + unit + "Count"], 0);
              
              if(lost > 0)
              {
                troopsLost += lost;
              }
            }
            
            if((troopsLost >= Options.crestLossThreshold))
            {
              t.toggleCrestState(document.getElementById('Cresttoggle'));
              new DisplayAlert('<SPAN class=boldRed>Crest Alert: Cresting stopped due to troop losses!</span>', null, null, mainPop.getMainDiv,null);
              return;
            }

            logit("Cresting: returning march [losses: " + troopsLost + "/" + unitsSent + "]");
          }
        }
      }
    }
  },
  
  marchStatus: function()
  {
    if(Options.marchCount > 0)
    {
      jQuery('#pbMarchStatus').text("Marches since captcha: " + Options.marchCount);
    }
    else
    {
      jQuery('#pbMarchStatus').text("Captcha Timeout Remaining: " + (Options.captchaDuration - Options.captchaTimer + 1));
    
    }
    
    Seed.playerEffects.fogExpire = 0;
  },
  
  
  helpPop : function ()
  {
    var helpText = '<BR>The crest tab is designed to attack one wild over and over again.<BR>';
    helpText += 'It will attack a wild in 2 waves, abandon it and start over.<BR>';
    helpText += 'So make sure u have 1 FREE SLOT in your castle for a wild!<BR>';
    helpText += 'Just fill in the coordinates, troops and hit "ON".<BR><BR>';
    helpText += 'Troop numers (from KOC WIKI):<BR>';
    helpText += '<A target="_tab" href="http://koc.wikia.com/wiki/Wilderness">More can be found on Koc Wikia</a>';
    helpText += '<TABLE width=100%><TR><TD>Level</td><TD>Wave 1</td><TD>Wave 2</td><TD>Troop loses</td><TD>Min. Fletching</td></tr>';
    helpText += '<TR><TD>1</td><TD>n/a</td><TD>160 MM</td><TD>12 MM</td><TD>0</td></tr>';
    helpText += '<TR><TD>1</td><TD>n/a</td><TD>80 archers</td><TD>None</td><TD>1+</td></tr>';
    helpText += '<TR><TD>2</td><TD>5 MM</td><TD>130 archers</td><TD>1st Wave</td><TD>2+</td></tr>';
    helpText += '<TR><TD>3</td><TD>10 MM</td><TD>520 archers</td><TD>1st Wave</td><TD>3+</td></tr>';
    helpText += '<TR><TD>4</td><TD>20 MM</td><TD>1600 archers</td><TD>1st Wave</td><TD>4+</td></tr>';
    helpText += '<TR><TD>5</td><TD>50 MM</td><TD>2200 archers</td><TD>1st Wave</td><TD>6+</td></tr>';
    helpText += '<TR><TD>6</td><TD>100 MM</td><TD>3000 archers</td><TD>1st Wave</td><TD>7+</td></tr>';
    helpText += '<TR><TD>7</td><TD>150 MM</td><TD>6000 archers</td><TD>1st Wave</td><TD>8+</td></tr>';
    helpText += '<TR><TD>8</td><TD>299 MM + 1Bal</td><TD>9000 archers + 900 Bal</td><TD>1st Wave + 1 Archer</td><TD>9+</td></tr>';
    helpText += '<TR><TD>9</td><TD>599 MM + 1Bal</td><TD>13000 archers + 900 Bal</td><TD>1st Wave + 2 Archer</td><TD>10</td></tr>';
    helpText += '<TR><TD>10</td><TD>1199 MM + 1Cat</td><TD>35000 archers + 2500 Cat</td><TD>1st Wave + 6 Archer + 50 Cat</td><TD>10</td></tr></table>';
    
    var pop = new pbPopup ('giftHelp', 0, 0, 650, 385, true);
    pop.centerMe (mainPop.getMainDiv());  
    pop.getMainDiv().innerHTML = helpText;
    pop.getTopDiv().innerHTML = '<CENTER><B>Power Bot Help: Cresting</b></center>';
    pop.show (true);
  },

  /** Add crest route **/
  addCrestRoute : function () 
  {
    if(CrestOptions.X == "" || CrestOptions.Y == "") 
    {
      alert("Please enter Coords");
      return;
    }
    
    var t = Tabs.Crest;
    var CrestLength = CrestData.length;
    
    CrestData[CrestLength] = new CrestFunc(CrestOptions);
    saveCrestData();

  },
  
  

  /** Show Crest Targets **/
  showCrestRoute : function () 
  {
    var t = Tabs.Crest;
    var popCrestTargets = null;

    t.popCrestTargets = new pbPopup('pbShowCrestTargets', 0, 0, 1100, 485, true, function() {clearTimeout (1000);});

    var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbShowCrestTargets" id="pbCrestTargets">';       

    t.popCrestTargets.getMainDiv().innerHTML = '</table></div>' + m;
    t.popCrestTargets.getTopDiv().innerHTML = '<TD><CENTER><B>Crest Targets</center></td>';
    t.paintCrestTargets();
    t._addTabHeader();
    t.popCrestTargets.show(true);
  },
  
  _addTabHeader : function () 
  {
    var row = document.getElementById('pbCrestTargets').insertRow(0);

    row.vAlign = 'top';
    row.insertCell(0).innerHTML = "City / Target";
    row.insertCell(1).innerHTML = "Wave #";
    row.insertCell(2).innerHTML = "SupTroop";
    row.insertCell(3).innerHTML = "MM";
    row.insertCell(4).innerHTML = "Scout";
    row.insertCell(5).innerHTML = "Pike";
    row.insertCell(6).innerHTML = "Sword";
    row.insertCell(7).innerHTML = "Arch";
    row.insertCell(8).innerHTML = "LC";
    row.insertCell(9).innerHTML = "HC";
    row.insertCell(10).innerHTML = "SupWagon";
    row.insertCell(11).innerHTML = "Balls";
    row.insertCell(12).innerHTML = "Ram";
    row.insertCell(13).innerHTML = "Cats";
    row.insertCell(14).innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;";
  },

  paintCrestTargets : function () 
  {
    t = Tabs.Crest;

    for(var i = 0; i < CrestData.length; i++) 
    {
      t._addTabCrest(i, "Attack: " + CrestData[i].X + "," + CrestData[i].Y, "Wave 2", CrestData[i].R2ST, CrestData[i].R2MM, CrestData[i].R2Scout, CrestData[i].R2Pike, CrestData[i].R2Sword, CrestData[i].R2Arch, CrestData[i].R2LC, CrestData[i].R2HC, CrestData[i].R2SW, CrestData[i].R2Ball, CrestData[i].R2Ram, CrestData[i].R2Cat, " ");
      t._addTabCrest(i, CrestData[i].CrestCity, "Wave 1", CrestData[i].R1ST, CrestData[i].R1MM, CrestData[i].R1Scout, CrestData[i].R1Pike, CrestData[i].R1Sword, CrestData[i].R1Arch, CrestData[i].R1LC, CrestData[i].R1HC, CrestData[i].R1SW, CrestData[i].R1Ball, CrestData[i].R1Ram, CrestData[i].R1Cat, "Delete");
      t._addTabCrest(i, "","","","","","","","","","","","","","","");
    }
  },

  _addTabCrest : function (QueID, col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11, col12, col13, col14) 
  {
    var t = Tabs.Crest;
    var row = document.getElementById('pbCrestTargets').insertRow(0);

    for (var i = 0; i <= 14; i++) 
    {
      if (i == 14 && col14 == "Delete") 
      {
        row.insertCell(i).innerHTML = "<a id=pbCrestDel_" + QueID + " value=" + i + ">Delete</a>";
        document.getElementById('pbCrestDel_' + QueID).addEventListener('click', function(){t.cancelCrestTarget(QueID);}, false);
      } 
      else if (col14 == "Delete" && i == 0) 
      {
        row.insertCell(i).innerHTML = (Cities.byID[col0] ? Cities.byID[col0].name : '');
      } 
      else 
      {
        row.insertCell(i).innerHTML = eval("col" + i) + "&nbsp; &nbsp;";
      }
    }
  },

  cancelCrestTarget : function (QueID) 
  {
    var t = Tabs.Crest;
    var queueId = parseInt(QueID);
    CrestData.splice(queueId, 1);
    saveCrestData();
    t.showCrestRoute();
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sendMarch: function(params, callback, r, retry, CrestDataNum)
  {
    var t = Tabs.Crest;     
    
    t.pendingCrest++;
    
    var _ajaxCall = function ()
    {
      var profiler = new CM.Profiler("ResponseTime", "march.php");
      new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
      { 
        method: "post",
        parameters: params,
        loading: true,
        crest: true,

        onSuccess: function (transport) 
        {   
          profiler.stop();
          var rslt = eval("(" + transport.responseText + ")");

          if(t.pendingCrest > 0) 
          {
            t.pendingCrest--;
          }

          logit("Cresting: Pending - " + t.pendingCrest);
          
          if (rslt.ok) 
          {
            addOutgoingMarch(params, rslt);
          
            if(r == 1)
            {
              Options.Crest1Count++;
              r = 2;
            } 
            else 
            {
              Options.Crest2Count++;
            }       
        
            var now = new Date().getTime() / 1000.0;
            now = now.toFixed(0);
            CrestData[CrestDataNum].lastRoundTwo = now;
            saveCrestData();
            
            CheckUpdateSeed(rslt);

            return;
          } 
          else 
          {
            if (rslt.user_action) 
            {
              var user_action = 
              {
                marchWarning: function() 
                {
                  logit('Captcha: [cresting] captcha warning');
                  actionLog('Captcha: [cresting] captcha warning');
                },
                marchCaptcha: function() 
                {
                  actionLog('Captcha: [cresting] triggered captcha');
                  logit('Captcha: [cresting] triggered captcha');
                  startCaptcha();
                },
                backOffWaitTime: function() 
                {
                  logit('Captcha: [cresting] back off time - ' + rslt.wait_time);
                  actionLog('Captcha: [cresting] back off time - ' + rslt.wait_time);
                  params.tt = rslt.tt;
                  setTimeout(_ajaxCall, rslt.wait_time * 1000)
                }
              };
              user_action[rslt.user_action].call();
            }
            else 
            {
              logit("Cresting: unknown failure");
              Options.lastMarchFailed = true;
            }
            
            return;
          }
        },
        
        onFailure: function () 
        {
          profiler.stop();
          // if we get here and the captcha timer is not 0 then our march was cancelled
          if(Options.captchaTimer == 0) 
          {
            logit("Cresting: comms error");
          }
          
          if(t.pendingCrest > 0) 
          {
            t.pendingCrest--;
          }
          return;
        }
      }, true); 
    }
    _ajaxCall();
    
    setTimeout (function(){callback(r, 0, CrestDataNum);}, Options.Crestinterval * 1000);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  abandonWilderness: function(tid, x, y, cid, callback, retry, CrestDataNum)
  {
    var t = Tabs.Crest;   
    
    if (!Options.crestRunning) return;
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    var cityID = cid;
    var tileid = tid;
    
    params.tid=tid;
    params.cid=cid;
    params.x=x;
    params.y=y;           
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/abandonWilderness.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,
      onSuccess:function(transport)
      {
        var rslt=eval("("+transport.responseText+")");
        
        if (rslt.ok) 
        {
          t.error_code = 0; 
          
          if (rslt.returningMarches) 
          {
            var cities = Object.keys(rslt.returningMarches);
            
            for (var i = 0; i < cities.length; i++) 
            {
              for (var j = 0; j < rslt.returningMarches[cities[i]].length; j++) 
              {
                var cid = cities[i].split("c")[1];
                var mid = rslt.returningMarches[cities[i]][j];
                var march = Seed.queue_atkp["city" + cid]["m" + mid];
                
                if (march) 
                {
                  var marchtime = Math.abs(parseInt(march.destinationUnixTime) - parseInt(march.marchUnixTime));
                  var ut = unsafeWindow.unixtime();
                  Seed.queue_atkp["city" + cid]["m" + mid].destinationUnixTime = ut;
                  Seed.queue_atkp["city" + cid]["m" + mid].marchUnixTime = ut - marchtime;
                  Seed.queue_atkp["city" + cid]["m" + mid].returnUnixTime = ut + marchtime;
                  Seed.queue_atkp["city" + cid]["m" + mid].marchStatus = 8
                }
              }
            }
          }
          
          CheckUpdateSeed(rslt);
          
          if (Object.keys(Seed.wilderness["city" + cityID]).length == 1) 
          {
            Seed.wilderness["city" + cityID] = []
          } 
          else  
          {
            delete Seed.wilderness["city"+cityID]["t"+tileid];
          }
        } 
        else 
        {
          if (rslt.error_code != 401) 
          {
            t.error_code = rslt.error_code;
          }
        }       
      },
    
      onFailure: function () 
      {
      }
    });
  },
  
  Rounds : function (r, retry, CrestDataNum) 
  {
    var t = Tabs.Crest;
    clearTimeout(t.timer);
    
    if (!Options.crestRunning || CrestData.length == 0) 
    {
      return;
    }

    if (CrestDataNum >= CrestData.length)
    {
      CrestDataNum = 0;
    }

    cityID = 'city' + CrestData[CrestDataNum].CrestCity;
    
    logit("Cresting: step 1");
    
    if(CrestData[CrestDataNum].isWild)
    {
      for (var k in Seed.wilderness[cityID] )
      {
        if (Seed.wilderness[cityID][k]['xCoord']==CrestData[CrestDataNum].X && Seed.wilderness[cityID][k]['yCoord']==CrestData[CrestDataNum].Y && t.error_code != 401) 
        {
          t.abandonWilderness(Seed.wilderness[cityID][k]['tileId']
            ,Seed.wilderness[cityID][k]['xCoord']
            ,Seed.wilderness[cityID][k]['yCoord']
            ,CrestData[CrestDataNum].CrestCity
            ,t.Rounds
            ,0
            ,CrestDataNum);
          break;
        }
      }
    }

    if ( parseInt(Seed.units[cityID]['unt1']) < CrestData[CrestDataNum].R1ST 
      || parseInt(Seed.units[cityID]['unt2']) < CrestData[CrestDataNum].R1MM 
      || parseInt(Seed.units[cityID]['unt3']) < CrestData[CrestDataNum].R1Scout 
      || parseInt(Seed.units[cityID]['unt4']) < CrestData[CrestDataNum].R1Pike 
      || parseInt(Seed.units[cityID]['unt5']) < CrestData[CrestDataNum].R1Sword 
      || parseInt(Seed.units[cityID]['unt6']) < CrestData[CrestDataNum].R1Arch 
      || parseInt(Seed.units[cityID]['unt7']) < CrestData[CrestDataNum].R1LC 
      || parseInt(Seed.units[cityID]['unt8']) < CrestData[CrestDataNum].R1HC 
      || parseInt(Seed.units[cityID]['unt9']) < CrestData[CrestDataNum].R1SW 
      || parseInt(Seed.units[cityID]['unt10']) < CrestData[CrestDataNum].R1Ball 
      || parseInt(Seed.units[cityID]['unt11']) < CrestData[CrestDataNum].R1Ram 
      || parseInt(Seed.units[cityID]['unt12']) < CrestData[CrestDataNum].R1Cat 
      || parseInt(Seed.units[cityID]['unt1']) < CrestData[CrestDataNum].R2ST 
      || parseInt(Seed.units[cityID]['unt2']) < CrestData[CrestDataNum].R2MM 
      || parseInt(Seed.units[cityID]['unt3']) < CrestData[CrestDataNum].R2Scout 
      || parseInt(Seed.units[cityID]['unt4']) < CrestData[CrestDataNum].R2Pike 
      || parseInt(Seed.units[cityID]['unt5']) < CrestData[CrestDataNum].R2Sword 
      || parseInt(Seed.units[cityID]['unt6']) < CrestData[CrestDataNum].R2Arch 
      || parseInt(Seed.units[cityID]['unt7']) < CrestData[CrestDataNum].R2LC 
      || parseInt(Seed.units[cityID]['unt8']) < CrestData[CrestDataNum].R2HC 
      || parseInt(Seed.units[cityID]['unt9']) < CrestData[CrestDataNum].R2SW 
      || parseInt(Seed.units[cityID]['unt10']) < CrestData[CrestDataNum].R2Ball 
      || parseInt(Seed.units[cityID]['unt11']) < CrestData[CrestDataNum].R2Ram 
      || parseInt(Seed.units[cityID]['unt12']) < CrestData[CrestDataNum].R2Cat) 
    {
      t.timer = setTimeout(function() { t.Rounds(1, 0, parseInt(CrestDataNum) + 1); }, Options.Crestinterval * 1000);
      logit("Cresting: not enough of required troops");
      return;
    }

    logit("Cresting: step 2");
    if (CrestData[CrestDataNum].R1ST == 0 && CrestData[CrestDataNum].R1MM == 0 && CrestData[CrestDataNum].R1Scout == 0 
     && CrestData[CrestDataNum].R1Pike == 0 && CrestData[CrestDataNum].R1Sword == 0 && CrestData[CrestDataNum].R1Arch == 0 
     && CrestData[CrestDataNum].R1LC == 0 && CrestData[CrestDataNum].R1HC == 0 && CrestData[CrestDataNum].R1SW == 0 
     && CrestData[CrestDataNum].R1Ball == 0 && CrestData[CrestDataNum].R1Ram == 0 && CrestData[CrestDataNum].R1Cat == 0) 
    {
       r = 2;
    }
    else 
    {
      var now = new Date().getTime() / 1000.0;
      now = now.toFixed(0);
      
      if (now > (parseInt(CrestData[CrestDataNum].lastRoundTwo) + 300)) 
      {
        r = 1;
      }
    }
    
    freeMarchSlots = getFreeMarchSlots(cityID);   
    var maxMarches = getMaxMarches(cityID);    

    var spareSlotsRequired = 0;
    
    // check if this is round one of a multi march
    if (r == 1)
    {
      //we need at least a couple of slots to be free before it makes sense to send the first march wave
      // TODO : should this really be 1
      spareSlotsRequired = 2;
    }

    if (freeMarchSlots - t.pendingCrest <= (Options.CrestFreeSlots + spareSlotsRequired)) 
    {
      t.timer = setTimeout(function(){ t.Rounds(1,0,parseInt(CrestDataNum)+1);},Options.Crestinterval*1000);
      logit("Cresting: no free slots");
      return;
    }

    var knt = getFreeKnight(cityID);
    
    if(knt.length > 0)
    {
      kid = knt[0].ID;
    }
    else
    {
      logit("Crest: No free knight");
      t.timer = setTimeout(function() { t.Rounds(r, 0, CrestDataNum); }, Options.Crestinterval * 1000);

      return;
    }
    
    var params      =   unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid      =   CrestData[CrestDataNum].CrestCity;
    params.type     =   4;
    params.kid      =   kid;
    params.xcoord   =   CrestData[CrestDataNum].X;
    params.ycoord   =   CrestData[CrestDataNum].Y;
    params.u1       =   CrestData[CrestDataNum]["R" + r + "ST"];
    params.u2       =   CrestData[CrestDataNum]["R" + r + "MM"];
    params.u3       =   CrestData[CrestDataNum]["R" + r + "Scount"];
    params.u4       =   CrestData[CrestDataNum]["R" + r + "Pike"];
    params.u5       =   CrestData[CrestDataNum]["R" + r + "Sword"];
    params.u6       =   CrestData[CrestDataNum]["R" + r + "Arch"];
    params.u7       =   CrestData[CrestDataNum]["R" + r + "LC"];
    params.u8       =   CrestData[CrestDataNum]["R" + r + "HC"];
    params.u9       =   CrestData[CrestDataNum]["R" + r + "SW"];
    params.u10      =   CrestData[CrestDataNum]["R" + r + "Ball"];
    params.u11      =   CrestData[CrestDataNum]["R" + r + "Ram"];
    params.u12      =   CrestData[CrestDataNum]["R" + r + "Cat"];
    
    // we need to check if this is round 1 as we may change the number of troops sent
    if(r == 1)
    {
      // if this is soon enough from last march then there are less traps to take out
      if (now < (parseInt(CrestData[CrestDataNum].lastRoundTwo) + 300)) 
      { 
        params.u2   =   Math.ceil((CrestData[CrestDataNum].R1MM / 10));
      } 
    }
    
    t.sendMarch(params,t.Rounds,r,0, CrestDataNum);
  },
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  toggleCrestState: function(obj) 
  {
    var t = Tabs.Crest;
    if (Options.crestRunning == true) 
    {
      Options.crestRunning = false;
      obj.value = "Crest = OFF";
      saveOptions();
    } 
    else 
    {
      Options.crestRunning = true;
      obj.value = "Crest = ON";
      
      for (crest in Options.Creststatus) 
      {
        owned = Seed.items['i' + crest];
        
        if (owned == undefined) 
        {
          owned=0;
        }
        
        Options.Creststatus[crest] = owned;
        Options.Crest1Count = 0;
        Options.Crest2Count = 0;
      }
      
      var now = new Date().getTime() / 1000.0;
      now = now.toFixed(0);
      Options.LastCrestReport = now;
      saveOptions();
      t.timer = setTimeout(function(){ t.Rounds(1, 0, 0);}, Options.Crestinterval * 1000);
    }
  },

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  // Function Name :
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  sendCrestReport: function()
  {
    if(!Options.crestreport || !CrestOptions.Running) 
      return;
      
    var t = Tabs.Crest;
    var now = new Date().getTime()/1000.0;
    now = now.toFixed(0);
    
    if (now < (parseInt(Options.LastCrestReport)+(Options.CrestMsgInterval*60*60))) 
      return;

    var total = 0;
    var wildtype =  '';

    switch (Options.CrestType) 
    {
      case '10':
        wildtype = unsafeWindow.g_js_strings.commonstr.grassland;
        break;
      case '11': 
        wildtype = unsafeWindow.g_js_strings.commonstr.lake;
        break;
      case '20': 
        wildtype = unsafeWindow.g_js_strings.commonstr.woods;
        break;
      case '30': 
        wildtype = unsafeWindow.g_js_strings.commonstr.hills;
        break;
      case '40': 
        wildtype = unsafeWindow.g_js_strings.commonstr.mountain;
        break;
      case '50': 
        wildtype = unsafeWindow.g_js_strings.commonstr.plain;
        break;
    }
    
    var message = 'Crest Stats: %0A';
    message += '%0A Crests Gained (for '+ Options.CrestMsgInterval +' hour of cresting) on a Level: '+Options.CrestLevel+' '+wildtype+'%0A';

    for (crest in Options.Creststatus) 
    {
      owned = Seed.items['i'+crest];
      
      if (owned == undefined) 
      {
        owned = 0;
      }
      
      if ((owned - Options.Creststatus[crest]) > 0) 
      {
        message +=  '<DIV><B>' + unsafeWindow.itemlist['i'+crest]['name'] +': '+ (owned - Options.Creststatus[crest]) +'%0A </b></div>';
      }
      else
      {
        message +=  unsafeWindow.itemlist['i'+crest]['name'] +': '+ (owned - Options.Creststatus[crest]) +'%0A';
      }
        
      total += (owned - Options.Creststatus[crest]);
      Options.Creststatus[crest] = owned;
    }
    
    message += '%0A Total Crests gained: '+ total +'%0A';
    message += '%0A Numbers of 1st Wave send: '+ Options.Crest1Count +'%0A';
    message += 'Numbers of 2nd Wave send: '+ Options.Crest2Count +'%0A';

    Options.Crest1Count = 0;
    Options.Crest2Count = 0;

    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.emailTo = Seed.player['name'];
    params.subject = "Crest Overview";
    params.message = message;
    params.requestType = "COMPOSED_MAIL";
    
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      
      onSuccess: function (message) 
      {
        var rslt = eval("(" + message.responseText + ")");
        if (rslt.ok) 
        {
          Options.LastCrestReport = now;
        } 
      },
      
      onFailure: function () 
      {
      },
    });

    saveOptions();
  },  

  hide : function ()
  {
    var t = Tabs.Crest;
  },

  show : function ()
  {
  },
 };
/** End Cresting tab **/

/****************************  Population Control Tab  ******************************/
Tabs.popcontrol = {
  tabOrder : 850,
  tabDisabled : false,
  tabLabel : 'Pop Control',
  myDiv : null,
  timer : null,
  timer_del : null,
  timer_cycle : null,
  del_count : 0,
  cycle_running : false,
  busy : false,
  cycle_step : 0,

  logtable : null,
  logmaxEntries: 300,
  loglast99 : [],

  init : function (div)
    {
    var t = Tabs.popcontrol;
    t.myDiv = div;
    var selbut=0;
    
    var m = '<DIV class=pbStat>Population Control</div>';

    m += '<table border=0 width="100%">'; 
    m += '<tr align=center>';
    m += '<td align=left><input type=submit id=pophelp_button value="HELP!"></td>';
    m += '<td align=center>Pick City:<span id=popcity></span></td>';
    m += '<td align=center>Population Gain per cycle: <span id=poptab_cycle_pop></span></td>';
    m += '</tr>';
    m += '</table>';
    
    m += '<DIV class=pbStat>City Requirements:</div>';
    m += '<table border="0" width="100%">';   
    m += '<tr>';
    m += '<td>Current Food: &nbsp<span id=poptab_cur_food></span></td>';
    m += '<td>Current Wood: &nbsp<span id=poptab_cur_wood></span></td>';
    m += '<td>Current Ore: &nbsp&nbsp<span id=poptab_cur_ore></span></td>';
    m += '<td>Current MM: <span id=poptab_cur_mm></span></td>';
    m += '</tr>';
    m += '<tr>';
    m += '<td>Needed Food: &nbsp<span id=poptab_needed_food></span></td>';
    m += '<td>Needed Wood: &nbsp<span id=poptab_needed_wood></span></td>';
    m += '<td>Needed Ore: &nbsp&nbsp<span id=poptab_needed_ore></span></td>';
    m += '<td>Needed MM: <span id=poptab_needed_mm></span></td>';
    m += '</tr>';
    m += '</table>';

    m += '<DIV class=pbStat>City Status:</div>';
    m += '<table border="0" width="100%">'; 
    m += '<tr align=center>';
    m += '<td>Maximum Idle Population: <span id=poptab_max_idle_pop></span></td>';
    m += '<td># Slots Used: <span id=poptab_slots_used></span><br></td>';
    m += '<td># of barracks: <span id=poptab_barracks></span></td>';
    //m += '<td> </td>';
    m += '</tr>';
    m += '<tr align=center>';
    m += '<td>Current Idle Population: <span id=poptab_cur_idle_pop></span></td>';
    m += '<td># Slots Free: <span id=poptab_slots_free></span></td>';
    m += '<td># of cottages: <span id=poptab_cottages></span></td>';
    //m += '<td> </td>';
    m += '</tr>';   
    m += '</table>';

    m += '<DIV class=pbStat>Commands:</div>';
    m += '<table border="0" width="100%">'; 
    m += '<tr align=center>';
    m += '<td><input type="submit" id="poptab_dismiss_mm" value="Dismiss MM" disabled></td>';
    m += '<td><input type="submit" id="poptab_queue_st" value="Queue Supply Troops" disabled></td>';
    m += '<td><input type="submit" id="poptab_del_queues" value="Delete All Queues" disabled></td>';
    m += '<td><input type="submit" id="poptab_run_cycle" value="Run cycle" disabled></td>';
    //m += '<td><input type="submit" id="poptab_test" value="Test"></td>';
    m += '</tr>';   
    m += '</table>';
  
    m += '<DIV class=pbStat>Action Log:</div>';

    m += '<DIV style="height:250px; max-height:250px; overflow-y:auto">';
    m += '<TABLE cellpadding=0 cellspacing=0 id=poptab_log class=pbTabLined>';
    m += '<TR><TD></td><TD width=95%></td>';
    m += '</table></div>';

    t.myDiv.innerHTML = m;

    t.logtable = document.getElementById('poptab_log');  
    var a = JSON2.parse(GM_getValue ('poptab_log_'+getServerId(), '[]'));
    if (matTypeof(a) == 'array')
      {
      t.loglast99 = a;
      for (var i=0; i<t.loglast99.length; i++)    t.addlogrow (t.loglast99[i].msg, t.loglast99[i].ts);
      }
    window.addEventListener('unload', t.onUnload, false);

    t.tcp = new CdispCityPicker ('popcityselect', document.getElementById('popcity'), true, null, selbut);
    
    document.getElementById('pophelp_button').addEventListener    ('click', function(){ t.helpPop(this);              } , false);
    document.getElementById('popcity').addEventListener           ('click', function(){ t.show_city (t.tcp.city.id);  } , false);
    document.getElementById('poptab_dismiss_mm').addEventListener ('click', function(){ t.dismiss_mm(t.tcp.city.id);  } , false);
    document.getElementById('poptab_queue_st').addEventListener   ('click', function(){ t.queue_st  (t.tcp.city.id);  } , false);
    document.getElementById('poptab_del_queues').addEventListener ('click', function(){ t.del_queues_start(t.tcp.city.id);  } , false);
    document.getElementById('poptab_run_cycle').addEventListener  ('click', function(){ t.run_cycle (t.tcp.city.id);  } , false);
    //document.getElementById('poptab_test').addEventListener ('click', function(){ t.btest (); } , false);
  
    },

  disable_btns : function ()
    {
    var t = Tabs.popcontrol;
    t.busy = true;
    document.getElementById('poptab_del_queues' ).disabled = true;
    document.getElementById('poptab_queue_st').disabled = true;
    document.getElementById('poptab_dismiss_mm').disabled = true;
    document.getElementById('poptab_run_cycle').disabled = true; 
    },

  onUnload : function ()
    {
    var t = Tabs.popcontrol;
    //if (!ResetAll) GM_setValue ('log_'+getServerId(), JSON2.stringify(t.last50));
    GM_setValue ('poptab_log_'+getServerId(), JSON2.stringify(t.loglast99));
    },
    
  addlogrow : function (msg, ts)
    {
    var t = Tabs.popcontrol;
    if (t.logtable.rows.length >= t.maxEntries) t.logtable.deleteRow(t.maxEntries-1);
    var row = t.logtable.insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = ts;
    row.insertCell(1).innerHTML = msg;
    },
  
  log : function (msg)
    {
    var t = Tabs.popcontrol;
    var ts = new Date().toTimeString().substring (0,8);
    for (postcity in Seed.cities) if (Seed.cities[postcity][0] == t.tcp.city.id) logcity = Seed.cities[postcity][1];
    msg = logcity + ": " + msg;
    t.addlogrow (msg, ts);
    while (t.loglast99.length >= 99)
    t.loglast99.shift();
    t.loglast99.push ({msg:msg, ts:ts});
    },

  hide : function (){         // called whenever the main window is hidden, or another tab is selected
    var t = Tabs.popcontrol;
    clearTimeout (t.timer);
  },
  
  show : function (){         // called whenever this tab is shown
    var t = Tabs.popcontrol;
    clearTimeout (t.timer);
    t.timer = setTimeout (t.show, 2000);
    t.show_city(t.tcp.city.id);
  },

  helpPop : function ()
    {
    var helpText = "";
    
    helpText += '<p>** This is a work in progress... If it gets stuck, refresh. By ADABman / Lurkin **';
    helpText += 'Probably a good idea to temporarily turn off auto transport, auto reassign, and auto train, when using this.';
    
    helpText += '<p>POPULATION CONTROL tab will help you convert your excess/useless millitiamen ';
    helpText += 'into massive amounts of idle population. Massive idle population is very useful ';
    helpText += 'to have before a might tournament starts, or if you want to do a massive siege ';
    helpText += 'build with a Merlins tutelage.';
    helpText += '</p>';
    
    helpText += '<p>The CITY REQUIREMENTS area displays the amount of resouces and Militiamen ';
    helpText += 'required for a \'full cycle\' of building massive idle population. If any of these ';
    helpText += 'requirements are not met, they will be displayed in red.';
    helpText += '</p>';
    
    helpText += '<p>The CITY STATUS area displays the maximum amount of population your cottages ';
    helpText += 'provide, and the current amount of idle population in your city. This area also ';
    helpText += 'shows the number of training queue slots total and in use.';
    helpText += '</p>';
    
    helpText += '<p>The COMMANDS area displays the buttons that automate this process:';
    helpText += '</p>';

    helpText += '<UL>';
    
    helpText += 'DISMISS MM BUTTON<BR><li>' + dismissBtn_help1 + '</li>';
    helpText += '<li>' + dismissBtn_help2 + '</li><BR>';
    
    helpText += 'QUEUE SUPPLY TROOP BUTTON<BR><li>' + queueBtn_help1 + '</li>';
    helpText += '<li>' + queueBtn_help2 + '</li><BR>';
    
    helpText += 'DELETE QUEUE BUTTON<BR><li>' + deleteBtn_help1 + '</li>';
    helpText += '<li>' + deleteBtn_help2 + '</li>';
    helpText += '<li>' + deleteBtn_help3 + '</li><BR>';
    
    helpText += 'RUN CYCLE BUTTON<BR><li>' + runcycleBtn_help1 + '</li>';
    helpText += '<li>' + runcycleBtn_help2 + '</li>';
    helpText += '<li>' + runcycleBtn_help3 + '</li><BR>';
  
    helpText += '</UL><BR>';
    
    //function CPopup (prefix, x, y, width, height, enableDrag, onClose)
    var pop = new pbPopup ('popcontrol_Help', 0, 0, 740, 600, true);
    pop.centerMe (mainPop.getMainDiv());  
    pop.getMainDiv().innerHTML = helpText;
    pop.getTopDiv().innerHTML = '<CENTER><B>Power Bot Help</b>:  Population Control</center>';
    pop.show (true);
    },

  show_city : function (cityId)
    {
    var t = Tabs.popcontrol;

    t.st_food = 50;
    t.st_wood = 150;
    //t.st_stone = 0;
    t.st_ore = 10;
    
    var green = '#03F003';
    var red =   '#F0303';

    t.max_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[1])).toFixed(0);
    t.cur_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[0])).toFixed(0);
    document.getElementById('poptab_max_idle_pop').innerHTML  = t.max_idle_pop;
    document.getElementById('poptab_cur_idle_pop').innerHTML  = t.cur_idle_pop;

    t.barracks = parseInt(getCityBuilding(cityId, CM.BUILDING_TYPES.BARRACK).count);
    t.cottages = parseInt(getCityBuilding(cityId, CM.BUILDING_TYPES.COTTAGE).count);
    t.slots_used = parseInt(Seed.queue_unt['city'+cityId].length);
    t.slots_free = parseInt(t.barracks - t.slots_used);
    document.getElementById('poptab_barracks').innerHTML = t.barracks;
    document.getElementById('poptab_cottages').innerHTML = t.cottages;
    document.getElementById('poptab_slots_used').innerHTML = t.slots_used;
    document.getElementById('poptab_slots_free').innerHTML = t.slots_free;

    t.cycle_pop = (parseInt(t.barracks) * parseInt(t.max_idle_pop)) + (parseInt(t.max_idle_pop) * 2);
    document.getElementById('poptab_cycle_pop').innerHTML = addCommas( t.cycle_pop / 2 );

    t.cur_food = parseInt(Seed.resources['city'+cityId].rec1[0]/3600);
    t.cur_wood = parseInt(Seed.resources['city'+cityId].rec2[0]/3600);
    //t.cur_stone = parseInt(Seed.resources['city'+cityId].rec3[0]/3600);
    t.cur_ore = parseInt(Seed.resources['city'+cityId].rec4[0]/3600);
    
    document.getElementById('poptab_cur_food').innerHTML = addCommas (t.cur_food);
    document.getElementById('poptab_cur_wood').innerHTML = addCommas (t.cur_wood);
    //document.getElementById('poptab_cur_stone').innerHTML = addCommas (t.cur_stone);
    document.getElementById('poptab_cur_ore').innerHTML = addCommas (t.cur_ore);
    
    t.needed_food = parseInt(t.cycle_pop) * parseInt(t.st_food);
    t.needed_wood = parseInt(t.cycle_pop) * parseInt(t.st_wood);
    //t.needed_stone = 0;//parseInt(t.cycle_pop) * parseInt(t.st_Stone);
    t.needed_ore = parseInt(t.cycle_pop) * parseInt(t.st_ore);
    
    document.getElementById('poptab_needed_food').innerHTML = addCommas (t.needed_food);
    document.getElementById('poptab_needed_wood').innerHTML = addCommas (t.needed_wood);
    //document.getElementById('poptab_needed_stone').innerHTML = addCommas (t.needed_stone);
    document.getElementById('poptab_needed_ore').innerHTML = addCommas (t.needed_ore);
    
    document.getElementById('poptab_needed_food').style.color = (t.needed_food  > t.cur_food?'red':'green');
    document.getElementById('poptab_cur_food').style.color = (t.needed_food  > t.cur_food?'red':'green');
    document.getElementById('poptab_needed_wood').style.color  = (t.needed_wood  > t.cur_wood?'red':'green');
    document.getElementById('poptab_cur_wood').style.color = (t.needed_wood  > t.cur_wood?'red':'green');
    //document.getElementById('poptab_needed_stone').style.color = (t.needed_stone > t.cur_stone?'red':'green');
    //document.getElementById('poptab_cur_stone').style.color = (t.needed_stone > t.cur_stone?'red':'green');
    document.getElementById('poptab_needed_ore').style.color = (t.needed_ore  > t.cur_ore?'red':'green');
    document.getElementById('poptab_cur_ore').style.color = (t.needed_ore  > t.cur_ore?'red':'green');

    t.needed_mm = t.cycle_pop;
    t.cur_mm = parseInt(Seed.units['city'+cityId]['unt2']);
    document.getElementById('poptab_needed_mm').innerHTML = addCommas(t.needed_mm);
    document.getElementById('poptab_cur_mm').innerHTML = addCommas(t.cur_mm);
    
    document.getElementById('poptab_needed_mm').style.color = (t.needed_mm  > t.cur_mm?'red':'green')
    document.getElementById('poptab_cur_mm').style.color = (t.needed_mm  > t.cur_mm?'red':'green')
    
    dismissBtn_help1 = "This button is used to quickly get your city to its maximum idle population allowed by dismissing just the right amount of militiamen.";
    dismissBtn_help2 = "This button will only light up when when your city is not at its maximum population, and then only if you have enough MM in your city to dismiss.";
    need_to_dismiss = parseInt(t.max_idle_pop - t.cur_idle_pop);
    dismissBtn = document.getElementById('poptab_dismiss_mm');
    if(parseInt(need_to_dismiss) > 0 && parseInt(need_to_dismiss) <= parseInt(t.cur_mm) && !t.busy && !t.cycle_running)
      {
      dismissBtn.disabled = false;
      dismissBtn.value = "Dismiss " + addCommas(need_to_dismiss) + " MM";
      }
    else
      {
      dismissBtn.disabled = true;
      dismissBtn.value = "Dismiss MM";
      }

    queueBtn_help1 = "This button is used to train all the idle population into Supply Troops.";
    queueBtn_help2 = "This button will only light up when your city is at full idle population, and then only if you have enough resources to train all those Supply Troops and at least 1 free training slot.";
    unitId = 1; 
    var res_ok = 0;
    for (var i = 1; i < 5; i++)
      {
      var res_need = parseInt(unsafeWindow.unitcost["unt" + unitId][i]) * 3600 * parseInt(t.cur_idle_pop);
      var res_have = parseInt(unsafeWindow.seed.resources["city" + cityId]["rec" + i][0]);
      if(parseInt(res_need) > parseInt(res_have)) { res_ok++; }
      }
    queueBtn = document.getElementById('poptab_queue_st');
    if(parseInt(t.slots_free) > 0 && parseInt(t.cur_idle_pop) >= parseInt(t.max_idle_pop) && parseInt(res_ok)==0 && !t.busy && !t.cycle_running)
      {
      queueBtn.disabled = false;
      queueBtn.value = "Queue " + addCommas(t.cur_idle_pop) + " Supply Troops";
      }
    else
      {
      queueBtn.disabled = true;
      queueBtn.value = "Queue Supply Troops";
      }

    deleteBtn_help1 = "This button is used to quickly delete all those queued up Supply Troops, returning 1/2 the used population (and resources?).";
    deleteBtn_help2 = "This button will only light up when there is at least 1 training queue slot used.";
    //deleteBtn_help3 = "** Due to a bug, you should refresh your game before using this button! **";
    deleteBtn_help3 = "If you have any problems with this button, refresh and try again.";
    deletebtn = document.getElementById('poptab_del_queues' );
    if(Seed.queue_unt['city'+cityId].length > 0 && !t.busy && !t.cycle_running)
      {
      deletebtn.disabled = false;
      deletebtn.value = " Delete " + Seed.queue_unt['city'+cityId].length + " Queues";
      }
    else
      {
      deletebtn.disabled = true;
      deletebtn.value = "Delete All Queues";
      }

    runcycleBtn_help1 = "This button is used to automate the entire process of repeatedly dismissing Militiamen then queueing Supply Troops, and then finally delete all of those queues.";
    runcycleBtn_help2 = "This button will only light up when your city has the required amount of resources and Militiamen";
    //runcycleBtn_help3 = "------ This button is disabled for now. -----";
    runcycleBtn_help3 = "If the queue slots wont delete, refresh and hit the 'Delete All Queues' button.";
    res_ok = 0;
    t.cycle_pop_continue = (parseInt(t.slots_free) * parseInt(t.max_idle_pop)) + (parseInt(t.max_idle_pop) * 2);
    for (var i = 1; i < 5; i++)
      {
      var res_need = parseInt(unsafeWindow.unitcost["unt" + unitId][i]) * 3600 * parseInt(t.cycle_pop_continue);
      var res_have = parseInt(unsafeWindow.seed.resources["city" + cityId]["rec" + i][0]);
      if(parseInt(res_need) > parseInt(res_have)) { res_ok++; }
      }
    runcycleBtn = document.getElementById('poptab_run_cycle');
    //if(parseInt(t.cur_idle_pop) >= parseInt(t.max_idle_pop) && parseInt(res_ok)==0 && !t.busy && !t.cycle_running)
    t.needed_mm_continue = t.cycle_pop_continue;
    if(parseInt(t.needed_mm) <= parseInt(t.cur_mm) && parseInt(res_ok)==0 && !t.busy && !t.cycle_running)
      {
      runcycleBtn.disabled = false;
      }
    else
      {
      runcycleBtn.disabled = true; 
      }
    
    },

  run_cycle : function (cityId)
    {
    // Temp disable auto train for this city & auto reassign & auto transport & auto refresh
    // log all that
    
    var t = Tabs.popcontrol;
    clearTimeout (t.timer);
    clearTimeout (t.timer_cycle);
    t.disable_btns();
    if(!t.cycle_running)
      {
      t.log("Starting population build cycle. Population at start: " + t.cur_idle_pop);
      t.cycle_running = true;
      t.cycle_step = 1;
      }
    
    //t.actionlog("1");
    t.max_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[1])).toFixed(0);
    t.cur_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[0])).toFixed(0);
    //num = parseInt(t.max_idle_pop) - parseInt(t.cur_idle_pop);
    if(parseInt(t.cur_idle_pop) < parseInt(t.max_idle_pop)) // Need to Dismiss MM
      {
      if (t.cycle_running)  t.dismiss_mm(cityId);
      
      //t.actionlog("2");
      }
    else if(parseInt(t.slots_free) > 0 && parseInt(t.cur_idle_pop) >= parseInt(t.max_idle_pop)) // Need to queue supply troops
      {
      if (t.cycle_running)  t.queue_st(cityId);
      //t.actionlog("3");
      }
    else if(parseInt(t.slots_free) == 0)  // Delete all the queues
      {
      //t.actionlog("4");
      t.cycle_running = false;
      setTimeout(unsafeWindow.update_seed_ajax, 250);
      t.del_queues_start(t.tcp.city.id);
      t.timer = setTimeout (t.show, 1000);
      return;
      }
    else
      {
      t.log("Waiting...");  // Wait
      }
    //t.actionlog("5");
    setTimeout(unsafeWindow.update_seed_ajax, 250);
    t.timer_cycle = setTimeout (function() {t.run_cycle(cityId)}, 3000);
    },

  dismiss_mm : function (cityId)
  {
    var t = Tabs.popcontrol;
    t.disable_btns();
    
    unitId = 2;

    t.max_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[1])).toFixed(0);
    t.cur_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[0])).toFixed(0);
    num = parseInt(t.max_idle_pop) - parseInt(t.cur_idle_pop);
    //t.log(num);
    
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid = cityId;
    params.type = unitId;
    params.quant = num;

    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/dismissUnits.php" + unsafeWindow.g_ajaxsuffix,
    {
      method: "post",
      parameters: params,
      onSuccess: function(rslt)
      {
        if (rslt.ok) 
        {
          //t.log("Dismissed "+ addCommas(num) +" "+ troops[unitId]);
          t.log("Dismissed "+ addCommas(num) +" Militiamen");
          Seed.units['city'+cityId]['unt'+unitId] -= num;
          
          CheckUpdateSeed(rslt);
          
          //setTimeout(unsafeWindow.update_seed_ajax, 250);
          t.busy = false;
          t.show_city(cityId);
          
          // Dismiss gets back 1/2 res ?
          //for (var i = 1; i < 5; i++)
          //  {
          //  var resourceGain = parseInt(unsafeWindow.unitcost["unt" + unitId][i]) * 3600 * parseInt(num) / 2;
          //  unsafeWindow.seed.resources["city" + cityId]["rec" + i][0] = parseInt(unsafeWindow.seed.resources["city" + cityId]["rec" + i][0]) + resourceGain;
          //  }
        }
        else
        {
          //t.log("FAILED to dismiss "+ addCommas(num) +" "+ troops[unitId] + " :(");
          t.log("FAILED to dismiss "+ addCommas(num) +" Militiamen :(");
          t.busy = false;
        }
      },
    });   
    setTimeout(unsafeWindow.update_seed_ajax, 250);
  },

  queue_st : function (cityId)
  {
    var t = Tabs.popcontrol;
    t.disable_btns();

    unitId = 1;
    num = t.cur_idle_pop;
    //num = 15;
    
    var time = unsafeWindow.modal_barracks_traintime(unitId, num);
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.cid = cityId;
    params.type = unitId;
    params.quant = num;
    params.gambleId = 0;

    new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/train.php" + unsafeWindow.g_ajaxsuffix,
    {
      method: "post",
      parameters: params,
      onSuccess: function(rslt)
      {
        if (rslt.ok) 
        {
          //t.log("Trained "+ addCommas(num) +" "+ troops[unitId]);
          t.log("Trained "+ addCommas(num) +" Supply Troops");

          CheckUpdateSeed(rslt);

          for (var i = 1; i < 5; i++)
          {
            var resourceLost = parseInt(unsafeWindow.unitcost["unt" + unitId][i]) * 3600 * parseInt(num);
            if(rslt.gamble) resourceLost = resourceLost*rslt.gamble[i];
            unsafeWindow.seed.resources["city" + cityId]["rec" + i][0] = parseInt(unsafeWindow.seed.resources["city" + cityId]["rec" + i][0]) - resourceLost;
          }

          unsafeWindow.seed.citystats["city" + cityId].gold[0] = parseInt(unsafeWindow.seed.citystats["city" + cityId].gold[0]) - parseInt(unsafeWindow.unitcost["unt" + unitId][5]) * parseInt(num);
          unsafeWindow.seed.citystats["city" + cityId].pop[0] = parseInt(unsafeWindow.seed.citystats["city" + cityId].pop[0]) - parseInt(unsafeWindow.unitcost["unt" + unitId][6]) * parseInt(num);
          //unsafeWindow.seed.queue_unt["city" + cityId].push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + time, 0, time, null]);
          unsafeWindow.seed.queue_unt["city" + cityId].push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + time, 0, rslt.ticksNeeded, null]);

          t.busy = false;
          t.show_city(cityId);
        }
        else
        {
          //t.log("FAILED to train "+ addCommas(num) +" "+ troops[unitId] + " :(");
          t.log("FAILED to train "+ addCommas(num) +" Supply Troops :(");
          t.busy = false;
        }
      },
    });
    setTimeout(unsafeWindow.update_seed_ajax, 250);
  },


  del_queues_start : function (cityId)
    {
    var t = Tabs.popcontrol;
    t.disable_btns();

    t.del_count = Seed.queue_unt['city'+cityId].length;
    t.log("Attempting to delete " + t.del_count + " Queue slots...");
    t.del_queues(cityId);
    },

  del_queues : function (cityId)
    {
    var t = Tabs.popcontrol;
    clearTimeout (t.timer_del);

    var q = Seed.queue_unt['city'+cityId];
    var qs = q.toString();

    if(q.length > 0 || t.del_count > 0)
      {
      t.del_count -= 1;
      typetrn =   q[0][0];
      numtrptrn = q[0][1];
      trnTmp =    q[0][2];
      trnETA =    q[0][3];
      trnNeeded = q[0][5];
      trainingId = 0;

      t.delete_queue_slot(typetrn, numtrptrn, trnTmp, trnETA, trnNeeded, cityId, trainingId)
      t.delete_queue_slot(typetrn, numtrptrn, trnTmp, parseInt(trnETA)-1, trnNeeded, cityId, trainingId)  //?!
            }
    else
      {
      t.log("No more queue slots to delete.");
      t.del_count = 0;
      t.busy = false;
      return;
      }
    setTimeout(unsafeWindow.update_seed_ajax, 250);
    t.timer_del = setTimeout (function() {t.del_queues(cityId)}, 1500);
    },

  delete_queue_slot : function (typetrn, numtrptrn, trnTmp, trnETA, trnNeeded, cityId, trainingId)
    {
    var t = Tabs.popcontrol;
    var uW = unsafeWindow;
    var params = uW.Object.clone(uW.g_ajaxparams);
    params.pf =0;
    params.requestType = "CANCEL_TRAINING";
    params.cityId = cityId;
    params.typetrn = typetrn;
    params.numtrptrn = numtrptrn;
    params.trnETA = trnETA;
    params.trnTmp = trnTmp;
    params.trnNeeded = trnNeeded;

    new AjaxRequest(uW.g_ajaxpath + "ajax/cancelTraining.php" + uW.g_ajaxsuffix,
    {
      method: "post",
      parameters: params,

      onSuccess: function (message)
      {
        var rslt=eval("("+message.responseText+")");

        if (rslt.ok)
        {
          t.log("Deleted queue of "+ addCommas(numtrptrn) +" "+ troops[typetrn]);
          CheckUpdateSeed(rslt);
          var k=0;
          for(var j=0;j<Seed.queue_unt["city"+cityId].length;j++)
          {
            if(j>trainingId)
            {
              Seed.queue_unt["city"+cityId][j][2]=parseInt(rslt.dateTraining[k]["start"]);
              Seed.queue_unt["city"+cityId][j][3]=parseInt(rslt.dateTraining[k]["end"]);
              k++;
            }
          }
          Seed.queue_unt["city"+cityId].splice(trainingId,1);
          for(var i=1;i<5;i++)
          {
            var totalReturn=parseInt(uW.unitcost["unt"+typetrn][i])*parseInt(numtrptrn)*3600/2;
            Seed.resources["city"+cityId]["rec"+i][0]=parseInt(Seed.resources["city"+cityId]["rec"+i][0])+totalReturn;
          }
        }
        else
        {
        }
      },
      onFailure: function ()
      {
      },
    });
  },
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tab: ascension
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Tabs.ascension = 
{
  tabLabel: 'Ascension',
  tabOrder: 300,
  myDiv: null,
  
  init: function (div) 
  {
      var t = Tabs.ascension;
      t.myDiv = div;
      var m = '<DIV id=pbAscensionMain></div><TABLE id=pbAscension><TR>';
      m += '<TD></td><TD>Percent</td><TD><CENTER>Menu</center></td><TD>Current Level</td><TD>Current Cost</td><TD>'+strButton20(translate('Building Values'), 'id=pbBuildingValues') +'</td><TR>';
      for (i = 0; i < Cities.cities.length; i++) 
      {
          var cityPrestige = Seed.cityData.city[Cities.cities[i].id].cityValue;
          var cityPrestigeLevel = Seed.cityData.city[Cities.cities[i].id].prestigeInfo.prestigeLevel;
          var isPrestigeCity = Seed.cityData.city[Cities.cities[i].id].isPrestigeCity;
          //alert('city - ' + Cities.cities[i].id + ' prestige= ' + isPrestigeCity )
          var currentGemPrice = null;
          var fullPrestige = 1200;
          var progressWidth = parseInt(((cityPrestige / fullPrestige) * 100));
          if (progressWidth > 100) progressWidth = 100;
          var fullBarWidth = 378;
          var gemFullPrice = 1250;
          m += '<TR><TD>City ' + Cities.cities[i].name + ' - </td>';
          m += '<TR><TD background="https://koc-power-bot.googlecode.com/svn/trunk/progress_brown_bar.png" width=' + fullBarWidth + ' height=25">';
          m += '<DIV id=pbGreenBar_' + i + '></div></td><TD align=center><DIV id=pbProgPerc_' + i + '></div></td><TD><INPUT id=pbAscendBtn_' + Cities.cities[i].id + ' type=submit value="Ascend"></td><TD align=center><DIV id=pbCityPrestigeLevel_' + i + '></div></td><TD align=center><DIV id=pbGemCost_' + Cities.cities[i].id + '></div></td><TD align=center><CENTER><DIV id=pbAscCurMight_'+i+'></div></center></td>';
      }
      div.innerHTML = m;
      document.getElementById('pbBuildingValues').addEventListener('click', function(){t.paintHelp();});
  },
  
  paintHelp: function() 
  {
    var t = Tabs.ascension;
    var helpText = translate("Ascension Building Values");
      helpText += '<TABLE><TR><TD align=center>Building</td><TD align=center width=50>Lvl 1</td><TD align=center width=50>+1 Lvl</td></tr>';

      helpText += '<TR><TD>Castle</td><TD><CENTER>10</center></td><TD><CENTER>+8</center></td></tr>';         
      helpText += '<TR><TD>Tavern</td><TD><CENTER>7</center></td><TD><CENTER>+6</center></td></tr>';
      helpText += '<TR><TD>Knights Hall</td><TD><CENTER>7</center></td><TD><CENTER>+6</center></td></tr>';
      helpText += '<TR><TD>Alchemy Lab</td><TD><CENTER>7</center></td><TD><CENTER>+6</center></td></tr>';
      helpText += '<TR><TD>Rally Point</td><TD><CENTER>7</center></td><TD><CENTER>+6</center></td></tr>';
      helpText += '<TR><TD>Wall</td><TD><CENTER>7</center></td><TD><CENTER>+6</center></td></tr>';
      helpText += '<TR><TD>DRUID Barracks (field)</td><TD><CENTER>7</center></td><TD><CENTER>+6</center></td></tr>';
      helpText += '<TR><TD>DRUID Apothecary (field)</td><TD><CENTER>6</center></td><TD><CENTER>+5</center></td></tr>';
      helpText += '<TR><TD>Embassy</td><TD><CENTER>6</center></td><TD><CENTER>+5</center></td></tr>';
      helpText += '<TR><TD>Market</td><TD><CENTER>6</center></td><TD><CENTER>+5</center></td></tr>';
      helpText += '<TR><TD>Watch Tower</td><TD><CENTER>6</center></td><TD><CENTER>+5</center></td></tr>';
      helpText += '<TR><TD>Spire</td><TD><CENTER>6</center></td><TD><CENTER>+5</center></td></tr>';
      helpText += '<TR><TD>Apothecary</td><TD><CENTER>6</center></td><TD><CENTER>+5</center></td></tr>';
      helpText += '<TR><TD>NORMAL Barracks</td><TD><CENTER>2</center></td><TD><CENTER>+2</center></td></tr>';
      helpText += '<TR><TD>Cottage</td><TD><CENTER>2</center></td><TD><CENTER>+2</center></td></tr>';
      helpText += '</table><TABLE>';
      helpText += '<TR><TR><TD>These numbers are for every added level of a building. Whether you are building it to level 2 or level 10, it will only add this amount to the total, shown under this help button. Every buildings "might" value combines to give the total. Once it reaches 1200, you are at 100% and can level up again.</td></tr></tr>';
      helpText += '</table>';

      var pop = new pbPopup ('ascensionHelp', 0, 0, 400, 400, true);
      pop.centerMe (mainPop.getMainDiv());  
      pop.getMainDiv().innerHTML = helpText;
      pop.getTopDiv().innerHTML = '<CENTER><B>Power Bot '+translate("Help")+': '+translate("Ascension")+'</b></center>';
      pop.show (true);
  },
  
  paintTab: function () 
  {
      for (i = 0; i < Cities.cities.length; i++) 
      {
          var cityPrestige = Seed.cityData.city[Cities.cities[i].id].cityValue;
          var cityPrestigeLevel = Seed.cityData.city[Cities.cities[i].id].prestigeInfo.prestigeLevel;
          var isPrestigeCity = Seed.cityData.city[Cities.cities[i].id].isPrestigeCity;
          //alert('city - ' + Cities.cities[i].id + ' prestige= ' + isPrestigeCity )
          var currentGemPrice = null;
          var fullPrestige = 1200;
          var progressWidth = parseInt(((cityPrestige / fullPrestige) * 100));
          if (progressWidth > 100) progressWidth = 100;
          var fullBarWidth = 378;
          var gemFullPrice = 1250;
          m += '<TR><TD>City ' + Cities.cities[i].name + ' - </td>';
          m += '<TR><TD style="background:https://koc-power-bot.googlecode.com/svn/trunk/progress_brown_bar.png" width=100% height=25">';
          if (isPrestigeCity) {
              if (cityPrestigeLevel < 3) {
                  //logit(cityPrestigeLevel + ' ' + isPrestigeCity)
                  document.getElementById('pbGreenBar_' + i).innerHTML = '<img src="https://koc-power-bot.googlecode.com/svn/trunk/progress_green_bar.png" width=' + progressWidth + '% height=25>'
                  document.getElementById('pbProgPerc_' + i).innerHTML = progressWidth + '%';
                  document.getElementById('pbCityPrestigeLevel_' + i).innerHTML = cityPrestigeLevel + '/3';
                  document.getElementById('pbAscCurMight_'+i).innerHTML = cityPrestige + '/1200';
              } else {
                  document.getElementById('pbGreenBar_' + i).innerHTML = '<CENTER><B>C O M P L E T E &nbsp;&nbsp;&nbsp; (for now)</center>'
                  document.getElementById('pbProgPerc_' + i).innerHTML = 'N/A';
                  document.getElementById('pbCityPrestigeLevel_' + i).innerHTML = 'N/A';
                  document.getElementById('pbAscCurMight_' + i).innerHTML = 'N/A';
              }
              m += '<TR>';
          } else {
              document.getElementById('pbGreenBar_' + i).innerHTML = '<CENTER><B>C I T Y &nbsp;&nbsp;&nbsp; N O T  &nbsp;&nbsp;&nbsp; A S C E N D E D &nbsp;&nbsp;&nbsp; Y E T</center>'
              document.getElementById('pbProgPerc_' + i).innerHTML = '<CENTER>N/A</center>';
              document.getElementById('pbCityPrestigeLevel_' + i).innerHTML = '<CENTER>0/3</center>';
              document.getElementById('pbAscCurMight_' + i).innerHTML = 'N/A';
          }
      }
  },
  
  clickCitySelect: function (city) {
      var t = Tabs.ascension;
      t.selectedCity = city;
      t.JumpCity(city);
      unsafeWindow.cm.PrestigeManagerController.open()
  },
  
  JumpCity: function (city) {
      var t = Tabs.ascension;
      for (i = 0; i < Seed.cities.length; i++) {
          if (Seed.cities[i][0] == city) var cityNum = i;
      }
      cityNum++;
      var obj = document.getElementById('citysel_' + cityNum);
      return t.ClickWin(window, obj, 'click');
  },
  
  ClickWin: function (win, obj, evtName) {
      var evt = win.document.createEvent("MouseEvents");
      evt.initMouseEvent(evtName, true, true, win, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
      return !obj.dispatchEvent(evt);
  },
  
  getGemCost: function (cityId, callback) {
      var t = Tabs.ascension;
      var isPrestigeCity = Seed.cityData.city[cityId].isPrestigeCity;
      var cityPrestigeLevel = Seed.cityData.city[Cities.cities[i].id].prestigeInfo.prestigeLevel;
      if (isPrestigeCity && cityPrestigeLevel < 3) {
          var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
          params.cid = cityId;
          params.prestigeType = 1;
          new MyAjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getPrestigeCost.php" + unsafeWindow.g_ajaxsuffix, {
              method: "post",
              parameters: params,
              onSuccess: function (rslt) {
                  if (rslt.ok) {
                      callback(cityId, rslt.cost, rslt.original_cost)
                  }
              }
          });
      } else {
          callback(cityId, null, null)
      }
  },
  
  show: function () 
  {
    var t = Tabs.ascension;
    t.Timer = setInterval(t.paintTab, 1000)
    
    for (i = 0; i < Cities.cities.length; i++) 
    {
      document.getElementById('pbAscendBtn_' + Cities.cities[i].id).addEventListener('click', function () 
      {
        var t = Tabs.ascension
        var what = this.id.substr(12); // strip first 12 char's -> pbAscendBtn_
        t.clickCitySelect(what);
      });
      
      var isPrestigeCity = Seed.cityData.city[Cities.cities[i].id].isPrestigeCity;
      
      if (isPrestigeCity) 
      {
        t.getGemCost(Cities.cities[i].id, function (cid, cost, origCost) {
          if (cost < 0 || cost == null || origCost == null) 
          {
            document.getElementById('pbGemCost_' + cid).innerHTML = '<CENTER>Max</center>';
          } 
          else 
          {
            document.getElementById('pbGemCost_' + cid).innerHTML = '<CENTER>' + cost + '/' + origCost + '</center>';
          }
        })
      } 
      else 
      {
        document.getElementById('pbGemCost_' + Cities.cities[i].id).innerHTML = '<CENTER>Not Ascended</center>';
      }
    }
  },
  
  hide: function () 
  {
    var t = Tabs.ascension;
    clearInterval(t.Timer)
  },
}
//
pbStartup ();